You are on page 1of 192

The Solaris

Operating System
on x86 Platforms
Crashdump Analysis
Operating System Internals
Table of Contents
1.Foreword............................................................................................................5
1.1.History of this document........................................................................................5
1.2.About modifying this document.............................................................................7
2.Introduction to x86 architectures............................................................... ......9
2.1.History and Evolution of the x86 architecture.......................................................
2.2.!haracteristics of x86..........................................................................................12
2.".#ar$eteering % &aming the architecture............................................................1
3.Assembly Lanuae on x86 !lat"orms.............................................................21
".1.'eneric (ntroduction to Assembly language........................................................21
".2.Assembly language on x86 )latforms..................................................................25
".".x86 assembly on *&(+ systems % calling conventions, A-(................................."2
"...!ase study/ !om)aring x86 and 01A2! assembly languages..............................2
".5.3he role of the stac$.............................................................................................6
".6.4dd things about the x86 instruction set............................................................55
".7.Exam)les of com)iler6generated code on x86 )latforms.....................................51
".8.Accessing data structures....................................................................................65
"..!om)iler hel) for debugging A#76. code..........................................................7"
#.$emory and %ri&ilee $anaement on x86....................................................''
..1.3he x86 )rotected mode % )rivilege management...............................................78
..2.3ra)s, (nterru)ts, 0ystem !alls, !ontexts...........................................................8
..".8irtual #emory #anagement on x86..................................................................1
....Advanced 0ystem 1rogramming 3echni9ues on x86.........................................151
5.Interru!t handlin( )e&ice Autocon"iuration.............................................1*3
5.1.(nterru)t Handling and (nterru)t 1riority #anagement...................................15"
5.2.A1(! and (4A1(! features.................................................................................15.
6.+olaris,x86 architecture................................................................................111
6.1.:ernel and user mode........................................................................................112
6.2.Entering the 0olaris;x86 $ernel.........................................................................11"
6.".0olaris;x86 8# architecture % x86 HA3 layer....................................................118
6...8irtual #emory <ayout......................................................................................121
6.5.!ontext s=itching..............................................................................................122
6.6.0u))orting #ulti)le !1*s.................................................................................12.
6.7.isaexec % !reating "2;6.bit6s)ecific a))lications..............................................125
'.+olaris,x86 -rashdum! Analysis...................................................................12'
7.1.7ebugging tools for core6;crashdum) analysis..................................................127
7.2.3roubleshooting system hangs on 0olaris;x86...................................................12
7."."2bit $ernel crashdum) analysis % a =ell6$no=n exam)le................................1"2
7...6.bit $ernel crashdum) analysis % =ell $no=n exam)le...................................155
7.5.Another 6.bit crashdum) analysis exam)le......................................................16"
7.6.A#76. A-( % -ac$tracing =ithout frame)ointers.............................................176
"
7.7.Exam)les on a))lication coredum) analysis on 0olaris;x86..............................177
7.8.Advanced 7ebugging 3o)ics..............................................................................178
8.Lab .xercises........................................................................... ......................1'9
8.1.(ntroduction to x86 assembly language.............................................................17
8.2.0tac$s and 0tac$tracing....................................................................................18"
9./e"erences.....................................................................................................185
1*.License................................................... ......................................................18'
.
1.Foreword
1.1.History of this do!ment
3his document didn>t start out from no=here, but neither has it originally been
intended for )ublication in boo$ form. -ut then, sometimes history ta$es unex)ected
)aths ...
0hortly after 0un had revised the ill6begotten idea of ?)hasing out@ 0olaris for x86
)latforms and started to ram) u) a hard=are )roduct line =ith (ntel !1*s in it, ( =as
a))roached by the 0ervice division =ithin 0un about =here they could get an
introductory course about ho= to )erform lo=6level troubleshooting % crashdum)
analysis % on the x86 )latform. (nformation and trainings about troubleshooting on this
level on 01A2! )latforms are =idely available % starting =ith the famous ?1anicA@ boo$
all the =ay to extensive classes offered by 0un Educational 0ervices to )artici)ants
both internal and external to 0un. 3hat not=ithstanding, =e soon found out that no
internal training about the lo=6level guts of 0olaris;x86 did exist. 7evelo)ment
engineers =ere usually both ca)able and encouraged to find out about the x86
)latform on their o=n, and users outside of the engineering s)ace =ere fe= and far
bet=een. 0o this )roBect started as a slide set for teaching engineers =ho =ere familiar
=ith 01A2! assembly, 0olaris (nternals and some !rashdum) Analysis the
fundamentals of x86 assembly and 0olaris on x86 )latforms, strongly focusing on
?=hat>s similar@ and ?=hat>s different@ bet=een the lo=6level 0olaris $ernel on 01A2!
and x86 )latforms.
( =as to a large degree sur)rised by the amount of interest this material generated
internally, so it gre=, as time allo=ed, into a multi6day internal course on 0olaris;x86
internals and crashdum) analysis. Cor a =hile, ( came to s)end a significant amount of
time teaching this never6official ?class@ ...
3hen came the =or$ on 0olaris 15 and the A#76. )ort. 3he ne= ?6.bit x86@ )latform
su))ort brought changes in the A-( =ith it that severely sur)rised even ex)erienced
?x86 old6timers@ and re9uired a large amount of addition to the existing material,
=hich at that time had gro=n into a braindum) of semi6related slides. 2evam)ing the
0olaris hard=are interface layer for both "2bit and 6.bit on x86;A#76. as =ell as the
addition of ne= features li$e 7trace or the <inux A))lication Environment made
further modifications necessary.
(n the end, 0tar4ffice>s limited ability to deal =ith )resentations of 255D slides
eventually made it inevitable to dro) the till6then ada)ted method of ?add a slide as a
ne= 9uestion comes u)@.
Eould ( have to ma$e the same choice again (>d )robably have o)ted to install myself a
3e+ system, but ( decided to give 0tar4ffice another chance and turn this material into
something closer to a boo$. Ho= ( regret not having used 3e+ to start =ith ... that>ll
teach me A
4ver the course of the A#76. )ort of 0olaris this gre= into essentially the current
form, and =hen )eo)le started using the 6.bit )ort internally a large amount of ne=
9uestions and ty)ical )roblems came u) =hich ( attem)ted to address. 3o say it
u)front, =hile the assembly language on A#76. =ill be immediately familiar to )eo)le
=ho $no= about ?classical@ x86, the calling conventions used in 6.bit machine code on
A#76. are so much different that in many as)ects crashdum) analysis on
0olaris;A#76. is closer to 0olaris;01A2! than it is to 0olaris;x86. -ut then it isn>t ...
=ell, (>m disgressing, go read the boo$.
3hen the 4)en0olaris )roBect came. (nitially, ( had )lanned to )ublish this on launch
1.Core=ord 5
day, but for many reasons this didn>t =or$ out at that time. 0o here it is % several
months delayed, no longer com)letely covering the state of our internal and external
F4)en0olarisG develo)ment releases. -ut it>s finally revie=ed, the crashdum) analysis
exam)le dum)s are made available, the 0tar4ffice document has been cleaned u) to
only rely on freely available fonts D gra)hics.
Ehich means that you % yes, loo$ into the mirror % are no= su))osed to =or$ =ith this
material, and on it. 3he =hole document including all illustrations are no= made
available in editable form.
1lease read the license attached to the end of the document.
Hes, you can ma$e modifications to this document.
Hes, you can redistribute co)ies of this document in any form you see fit % you>re in
fact encouraged to do so.
Hes, you>re encouraged to contribute corrections or additions.
Cor all else legalese, see the a))endix.
I 255"62555, Cran$ Hofmann, 0un #icrosystems, (nc.
EnBoy % and never forget/
Don't panic !
F0hall ( say green is my favourite color JG
(f you =ish to contact the author, )lease send Email to/
Frank.Hofmann@sun.com
At this )oint in time, ( cannot even start listing the number of )eo)le that have made
this document )ossible. 'iven that it didn>t start as a boo$ )roBect (>ve $e)t a lousy
bibliogra)hy.
(>d li$e to both than$ every unnamed contributor as =ell as excuse myself for not
naming you.
*sing the =ords of (saac &e=ton/
If I have seen further it is by
Standing on the shoulder of giants.
Hou $no= =ho you are.
6 1.Core=ord
1.".#bo!t modifying this do!ment
0tar4ffice8 is used to edit this document, but F-etaG versions of 4)en4ffice 2.x should
be able to access it as =ell.
3he document uses the 4)en0ource DejaVu fonts =hich are a derivative of -it0tream
8era. 3he difference bet=een these t=o is that the 7eBa8u font family contains full
bold;italic;bolditalic;condensed ty)efaces for 0ans, 0erif and #onos)aced, =hile the
original -itstream 8era fonts only su))ly the full ty)eface set for 0ans. (nstalling the
7eBa8u fonts is therefore a )rere9uisite to being able to edit this document and
recreate the out)ut as6is.
3hese fonts are available from htt)/;;deBavu.sourceforge.net
4ther fonts than 7eBa8u should not be used. 3o sim)lify this, s=itch the 0tar4ffice
stylist tools to only sho= ?A))lied 0tyles@, and don>t use any but these.
(f you =ish to contribute bac$ changes;additions in )lain text that>s more than
=elcome. (f you modify the 0tar4ffice document itself, allo= sim)le merge bac$ by
enabling the change recording facility in 0tar4ffice. 0ee the hel) functionality, on
?!hanges@.
&ote that 0tar4ffice>s master text facility is some=hat dumb % it records full
)athnames Finstead of relative locationsG for the subdocuments. Ehen you o)en
book.odm in 0tar4ffice8, the &avigator =ill sho= you the list of subdocuments. *se the
right mousebutton to re9uest the context menu, and choose ?Edit <in$@ to change the
)athnames of the subdocuments to refer to the location =here you un)ac$ed the file
set.
3he same is true for embedding gra)hics. &ot even the documented functionality
F?lin$@ to the illustrations instead of instantiate a co)y for the documentG is =or$ing.
0o be a=are =hen you change some file under figures/, you might need to delete and
reinsert it in the main document ...
(>ll $ee) a )ointer to the current version F0tar4ffice for editing ; 17C for reading and
)rintingG of this document on my blog/
http://blogs.sun.com/ambiguous/
And finally/ 3hese instructions should be better ...
1.Core=ord 7
".$ntrod!tion to x86 arhitet!res
".1.History and %&ol!tion of the x86 arhitet!re
3he main driving force in develo)ment of the x86 )rocessor family has al=ays been to
enhance existing functionality in such a =ay that full binary6level com)atibility =ith
)revious x86 )rocessors can be maintained. Ho= im)ortant this is to (ntel is best
described in (ntel>s o=n =ords/
One of the most important achievements of the IA!" architecture is
that the ob#ect code programs created for these processors starting
in $%&' still e(ecute on the latest processors in the IA!"
architecture family.
Among all !1* architectures still available in current machines, only the (-#"xx
mainframe architecture Ffirst introduced in 16. =ith the (-#"65, still available in the
(-# K0eries mainframesG has a longer history of unbro$en binary bac$=ard
com)atibility. All current ?x866com)atible@ !1*s still su))ort and im)lement the full
feature set of the original member of the x86 family, the (ntel 8586 !1* =hich =as
introduced in 178.
3his means/ Executable )rograms from code originally =ritten for the 8586 =ill run
unmodified on any recent x866com)atible !1* such as (ntel>s 1entium6(8 or A#7>s
4)teron )rocessor. Hes, #0740 1.5 is 9uite li$ely to run on the very latest and
greatest L1!6com)atibleL, )rovided you can still find some single6sided "65$- 5ML
2.(ntroduction to x86 architectures
Illustration ! "#er#ie$ of the %&' architecture e#olution
1978
i8086
16 bit
1MB RAM
8 Registers
segments
16 bit
1MB RAM
8 Registers
segments
1982
i80286
still 16 bit
16MB RAM
8 Registers
protected mode
1985
i80386
32bit
4GB RAM
32bit MMU
A32 !rc"itect#re
32bit
4GB RAM
32bit MMU
$#'" arhitet!re
1987
i80486
integr!ted $%U
on&c"ip c!c"e
1993
%enti#m
1997
%enti#m&
64GB RAM '%A()
on&c"ip 2
nd
l*l+ c!c"e
1999
%enti#m&
,,( e-tension
l!rge p!ges
,M% s#pport 'A%.)
MM/ e-tension
2000
%enti#m 4
,,(2 e-tension
R,. intern!ll0 1 23ps
2003
AM4 3pteron
64bit
2565B *irt#!l memor0
16 registers
#()6* arhitet!re
flo))y drive =hich =ould allo= you to boot it on that shiny ne= A#7 4)teron
=or$station.
-ac$=ard com)atibility of the x86 )rocessor family goes =ay beyond =hat most other
!1* architectures Fincluding 01A2!G have to offer. 0un #icrosystem>s 0olaris;01A2!
binary com)atibility guarantee only ensures that applications Fnot o)erating systems
or other lo=6level codeG =ritten on and for )revious 40;hard=are =ill continue to run
on recent 40;hard=are combinations, but it does not claim that old versions of the
0olaris 4)erating Environment =ill run on )rocessors that =ere yet unreleased at the
time a s)ecific release shi))ed. 3his is different on x86. &e= versions of x86 !1*s
from =hatever vendor run older o)erating systems Bust fine. (ncom)atibilities if at all
rise from the lac$ of device driver su))ort for ne=er integrated )eri)herals, but not
from the ne=er !1*>s inability to function li$e its )redecessors.
0ince introduction of the (ntel i85"86 in 185 FAG, most features of the x86 architecture
have remained remar$ably constant. 0#1 su))ort Fvia A1(!G and su))ort for more
than .'- )hysical memory Fvia 1AEG =as added in the 1entium res)ectively to the
1entium1ro )rocessorsN after that, only instruction set extensions F##+, 00EG =ere
added but no externally6visible changes =ere done to other core subsystems of x86.
Crom the )oint of vie= of 0olaris;x86, it =as never necessary therefore to have more
than one $ernel, /platform/i86pc/kernel/unix, for su))orting the o)erating system
on x86 )rocessors. 1ut this in context and com)are it =ith 0olaris in 01A2!/ Cor the
various 01A2! generations Fmaximum number of architectures concurrently
su))orted in 0olaris 2.6/ sun., sun.c, sun.d, sun.m, sun.u, sun.u1G, each time
se)arate )latform su))ort =as re9uired. Even today, 0olaris delivers ten FAG different
$ernels for the various 01A2! )latforms, =hile 0olaris for x86 still has only one.
3his strict insistence on binary com)atibility =ith its )redecessors obviously has
disadvantages as =ell. 3he =ay ho= the i85"86 introduced "2bit su))ort in some areas
loo$s illogical and counterintuitive, es)ecially =hen com)aring it =ith "2bit
architectures that =ere designed for "2bit from their very beginnings. 0ome exam)les
of this =ill be given later.
After releasing the i85"86 "2bit )rocessor, (ntel decided to $ee) future versions of
x866com)atible F?(A"2@ in (ntel>s termsG !1*s on "2bit. Each generation became faster
and added functionality, but the limitation to "2bit remained. (n the early 15s, this
did not seem a )roblem because the maBor mar$ets for x86 at that time F#icrosoft 740
and Eindo=sG =ere 16bit only any=ay, and (ntel>s evolutionary )ath to 6.bit had been
layed out in the agreement =ith H1 to co6develo) a ne= 6.bit architecture/ (A6., then
dubbed ?#erced@, is today found in the (ntel (tanium )rocessors.
-ut (A6. has nothing to do =ith x86. 3he instruction sets have nothing in common and
existing )rograms or o)erating systems =ritten for "2bit x86 )rocessors cannot run on
machines =ith (A6.;(tanium )rocessors in it. 3he (tanium, though )roduced by (ntel, is
a genetic child of H1>s 1A62(0! architecture, but only a distant relative to (ntel>s o=n
x86;(A"2.
(n addition to that, (ntel and H1 =ere late at delivering the (A6. !1* % very late.
0o late that bac$ in 2555, A#7 ste))ed in and decided to extend the old x86
architecture another time % to 6.bit. A#7 had, =ith varying success, been building
x866com)atible )rocessors since the early 185s and sa= (ntel>s de6facto termination
of x86 as a chance to extend its o=n mar$et reach. 3he A#76. F6.bit x86G
architecture =as done in a =ay very similar to ho= (ntel had done the i85"86, and
)rocessors based on A#76. Fmuch unli$e (tanium;(A6.G are, in good old x86 tradition,
fully binary bac$=ard com)atible. 4f course, actually using the ne= 6.bit o)erating
mode re9uires )orting o)erating system and a))lications Fli$e using "2bit on the
15 2.(ntroduction to x86 architectures
i85"86 did re9uire at the timeG. -ut even =hen running a 6.bit o)erating system does
A#76. )rovide a sandboxed "2bit environment to run existing a))lications in Fagain,
li$e the i85"86 =hich allo=ed the same for 16bit )rograms running on a "2bit 40G.
3herefore the A#76. architecture offers much better investment )rotection than (A6.
% =hich =ill not run existing "2bit o)erating systems or a))lications.
-y the time the A#7 4)teron 6.bit )rocessor became available, the (tanium, on the
mar$et for three years then, had seen very little ado)tion % =hile users and soft=are
vendors $e)t )ushing ever harder on (ntel to follo= A#7>s lead and )rovide 6.bit
ca)abilities in their x86 )rocessor line as =ell. (ntel resisted this for several years in
order not to Beo)ardiKe the mar$et for their (tanium )rocessors but eventually gave in
and cloned A#76.. Cor obvious reasons (ntel doesn>t call their 6.bit6ca)able x86
)rocessors ?A#76.6com)atible@ but uses the term E#6.3 F(nhanced )emory '*bit
+echnologyG for the architecture and (A"2e for the 6.bit instruction set extension.
(ntel !1*s =ith E#6.3 are com)atible to A#76. % =hich (ntel confirms in the CAO
for the 6.bit Extension 3echnology.
http://$$$.intel.com/technology/'*bite%tensions/fa,.htm notes that/
)%: (s it )ossible to =rite soft=are that =ill run on (ntel>s )rocessors =ith
(ntelP E#6.3, and A#7>s 6.6bit ca)able )rocessorsJ
A%: -es. in most cases. (#en though the hard$are microarchitecture for
each company/s processor is different. the operating system and soft$are
ported to one processor $ill likely run on the other processor due to the
close similarity of the instruction set architectures.
Ho= the future of x86 =ill loo$ remains to be seen. -ut the x86 architecture, =ith
more than 25 years of age, has far sur)assed the success of all other Fnon6embeddedG
)rocessor architectures ever develo)ed. Eith 6.bit extensions that have reBuvenated
x86, and x866com)atible )rocessors =ith 6.bit ca)abilities becoming common)lace
no=, this is unli$ely to change in the near future.
2.(ntroduction to x86 architectures 11
".".Charateristis of x86
3here are t=o factors res)onsible for the main characteristics of the machine
instruction set for =hat is commonly termed ?x86 architecture@/
3he long history of x86 has left its mar$ on the instruction set.
x86 machine code carries a huge legacy of Fmis6Gfeatures from the time =hen the
architecture =as still 16bit only, and in )arts even from )re6x86 8bit days Fin the
form of limited com)atibility =ith the (ntel 8558G.
3he need to introduce ne= ca)abilities =ithout brea$ing binary com)atibility has
lead to a lot of instruction set extensions that are o)tional, and =hose )resence
needs to be detected by a))lications ; o)erating systems that =ant to ma$e use of
them. (n addition, x86 never =as a vendor6loc$ed6in architecture, even though
(ntel>s decisions have dominated its evolution. -oth o)erating systems and
a))lication code for x86 therefore needs to ex)end some efforts on determining
=hich !1* by =hat vendor it runs on, and =hat instruction set extensions this !1*
)rovides before it can ma$e use of o)timiKed code.
3his is fortunately much im)roved by A#76. =hich establishes a ne= ?6.bit x86
baseline@.
(n addition to that, x86 !1*s use the so6called little endian =ay of ordering data in
memory. Endianness becomes very relevant once data needs to be exchanged bet=een
systems of differing architecture.
".".1.C$SC and +$SC
-ac$ in the early days of !1* design in the 175s and early 185s, manufacturing
technology did not allo= for anything close to the com)lexity =e have today. !1*
designers then had to ma$e tradeoffs, mostly bet=een a feature6rich assembly
language, but fe= registers and generally lo=er instruction through)ut, and a feature6
)oor assembly language =ith many registers and faster execution for the sim)le
instructions that there =ere.
3he x86 architecture is the classical exam)le of a so6called !(0! )rocessor. 3he term
0I10 stands for 0omple% Instruction 1et 0omputer, and is used to describe a )rocessor
=hose instruction set offers single, dedicated !1* instructions for )ossibly very
involved tas$s. 1hiloso)hically, the ultimate design goal for a !(0! )rocessor is to
achieve a 1/1 match bet=een !1* instructions and instructions in a high6level
)rogramming language.
!(0! is almost a re9uirement for !1*s =hich maintain full bac$=ard com)atibility
such as the x86 family. Adding functionality to an existing architecture al=ays means
adding instructions and com)lexity. A )ure evolutionary !1* develo)ment as (ntel has
done it therefore almost necessitates a !(0! architecture.
All in all, (ntel>s latest instruction set reference needs t=o volumes and more than
1555 )ages to describe all x86 instructions su))orted by the latest x86 !1*s by (ntel.
Cor com)arison 6 the s)arcv architecture reference manual only has 156 )ages
describing all s)arcv assembly instructions.
'iven the focus on instruction functionality vs. versatility, !(0! architectures tend to
have features li$e/
many s)ecial6)ur)ose instructions.
An exam)le on x86 =ould be t=o se)arate instructions for com)arison % the generic
CMP instruction and the TEST instruction =hich =ill only chec$ for e9uality or
Keroness.
12 2.(ntroduction to x86 architectures
the ability to modify a memory location directly, =ithout the need to load its
contents into a register first.
3his is done to offset the lac$ of registers % the idea is that if destination or source
of an o)eration can be memory, less registers are needed.
instructions =ith varying length.
3his is both due to the fact that !(0! architectures usually allo= to embed FlargeG
constants into the instruction, and because feature additions over time have
re9uired the introduction of longer o)codes Finstruction encodingsG.
Another conse9uence of this is that there are fe= ga)s Fundefined or illegal
o)codesG in the instruction set. As =e =ill see, to an x86 !1* random data ma$es u)
for a decodeable instruction stream A
fe= general6)ur)ose registers.
Historically there had to be a tradeoff bet=een using the s)ace on the !1* die to
)rovide more registers or more6ca)able instructions. !(0! !1* designers chose to
do the latter, and it often )roved difficult to extend the register set even after
manufacturing technologies =ould have allo=ed for it. 3he x86 architecture lived
=ith only eight registers, until A#7 designing the 6.bit mode finally too$ the
chance and extended the register set to 16.
3he x86 architecture is the single maBor remaining !(0! architecture out there today.
#ost other !1* architectures on the mar$et today, =hether 01A2!, 1o=er1!, A2# or
Fto a degreeG even (A6., have gone the other =ay % 2(0!.
S*A+, assembly source binary machine code disassembler output
func:
tst i!
orcc g!" i!" g!
set #$%&" i!
or g!" #$%&" i!
cmp i!" i#
subcc i!" i#" g!
clr i!
or g!" g!" i!
mo' i#" i!
or g!" i#" i!
.si(e func".)func
section .text
!: 8! *! !! #8
&: 8! *! !! #8
8: b! #! $& d$
c: b! #! $& d$
#!: 8! a6 !! #*
#&: 8! a6 !! #*
#8: b! #! !! !!
#c: b! #! !! !!
$!: b! #! !! #*
$&: b! #! !! #*
section .text
tst i!
tst i!
mo' !x&d$" i!
mo' !x&d$" i!
cmp i!" i#
cmp i!" i#
clr i!
clr i!
mo' i#" i!
mo' i#" i!
Illustration ! machine code e%ample on 2I10. synthetic instructions
01A2! and all its incarnations are a classical exam)le of 2I10 F2educed Instruction
1et 0omputerG, and share many generic features =ith other 2(0! architectures/
<ots and lots of !1* registers are available. Cor exam)le, 01A2! )rovides at least
"2 general6)ur)ose registers Finternally hundreds, via register =indo=sG.
3o modify data in memory, one must load it into a register, modify the register
contents and store the register bac$ into memory. 3his is called a load!store
architecture.
2(0! instructions usually have a fixed instruction siKe. All 01A2! instructions, for
exam)le, are "2bit. 2(0! (nstruction sets are rather designed than e#ol#ed.
(nstructions often are multi6)ur)ose. A 2(0! !1*, for exam)le, may not have
se)arate instructions for subtracting values, com)aring values or testing values for
Kero % instead, ty)ically, ?0*-@ =ill be used but the result Fa)art from condition
bitsG be ignored. 0ee the 01A2! assembly code exam)le above.
(nstructions tend to be sim)le. (f a 2(0! !1* offers com)lex instructions at all, they
2.(ntroduction to x86 architectures 1"
are usually com)leted by hel) of the o)erating system 6 instructions leading to
com)lex system activity =ill tra) and re9uire soft=are hel) to finish.
*nli$e !(0!, the focus for 2(0! is on ra= execution )o=er 6 the more instructions )er
unit of time a !1* can )rocess the faster it =ill be in the end. Executing a doKen
sim)le instructions as fast as theoretically )ossible often )roves to )rovide better
through)ut than executing a single, slo= instruction to achieve the same effect. 2(0!
originally =as invented to allo= for sim)ler !1* designs running at higher cloc$
s)eed.
2(0! )ays for this by often re9uiring more instructions to achieve an e9uivalent result
as !(0! gets =ith Bust one or t=o instructions/
('- assembly binary code S*A+, assembly binary code
mo'+
,!x#$%&-6.8*abcdef!"
rax
add+ rax"'ar
&8 b8
f! de bc *a
.8 -6 %& #$
&8 !# !& $-
XX XX XX XX
set/i /i0!x#$%&-&!!1" o#
xor o#" )!x$.*" o#
set/i /i0!x6-&%$!!!1" o!
xor o!" )!x##!" o!
sllx o#" %$" o#
xor o#" o!" o!
set/i /i0'ar1" o#
or o#" lo0'ar1" o#
ldx 2o#3" o$
addc o!" o$" o$
stx o$" 2o#3
#% !& 8d #-
*$ #a .d 8.
## #* -! c8
*! #a %e f!
*% $a .! $!
*! #a &! !8
#% !X XX XX
*$ #$ 6X XX
d& -a &! !!
*& &$ !! !a
d& .$ &! !!
Illustration 3 ! 2I10 4 0I10: 5dding a '*bit constant to a global #ariable 6var7
3oday, most arguments in the !(0! vs. 2(0! debate have become obsoleted by
technical )rogress.
0ince the introduction of (ntel>s 1entium6(8 and A#7>s Athlon, modern x86 )rocessors
internally Lrecom)ileL x86 instructions into 2(0! instruction sets. (ntel calls this Q6o)s,
=hile A#7 uses the term 241s F2(0! o)sG o)enly. 3hese 2(0! execution engines in
x86 !1*s are not ex)osed to the user 6 the ste) of decoding;com)iling x86 instructions
into the underlying micro6o)s is done by an additional layer of hard=are in the
instruction decoder )art of these !1*s.
<i$e=ise, 2(0! !1*s over time have added com)lex instructions such as hard=are
multi)ly;divide =hich had to be done )urely in soft=are in early 2(0! designs.
Additionally, instruction set extensions li$e the 8isual (nstruction 0et F8(0G on
*ltra01A2! or Alti8ec on 1o=er1! allo= for 7016li$e F0(#7G functionality Bust li$e
##+;00E do on x86.
0o =hat is a modern x86 !1* then J !(0! or 2(0! J
3he ans=er is/
-oth. (t is a !(0! !1*, but to )erform best, one has to )rogram it li$e a 2(0! !1*.
Cor exam)le, A#7 in their 1oft$are "ptimi8ation 9uide for 5)D 5thlon'* and 5)D
"pteron :rocessors ex)lains it li$e this/
+he 5)D'* instruction set is comple%; instructions ha#e #ariable!length
encodings and many perform multiple primiti#e operations. 5)D 5thlon '*
and 5)D "pteron processors do not e%ecute these comple% instructions
directly. but. instead. decode them internally into simpler fi%ed!length
instructions called macroops. :rocessor schedulers subse,uently break
do$n macro!ops into se,uences of e#en simpler instructions called micro
ops. each of $hich specifies a single primiti#e operation.
1. 2.(ntroduction to x86 architectures
and a little later/
Instructions are classified according to ho$ they are decoded by the
processor. +here are three types of instructions:
Instruction .ype Description
Direct:ath 1ingle 5 relati#ely common instruction that the processor
decodes directly into one macro!op in hard$are.
Direct:ath Double 5 relati#ely common instruction that the processor
decodes directly into t$o macroops in hard$are.
Vector:ath 5 sophisticated or less common instruction that the
processor decodes into one or more < ... = macro!ops < ... =
.
and finally/
>se Direct:ath instructions rather than Vector:ath instructions.
(n short/
-y)ass the !(0! runtime translation layer to get best )erformance out of the
underlaying 2(0! execution engine.
0imilar notes can be found in the res)ective manuals for (ntel>s 1entium (8 !1* family
and later.
2.(ntroduction to x86 architectures 15
".".".%ndianness
3he x86 !1* family is traditionally ?ittle (ndian. Ehat does this mean J
3he to)ic of ho= bytes that form multi6byte For, for that matter, multi6bitG entities
should be ordered in the )ast used to have almost religious traits. 3his is the reason
=hy the technical term for memory byte ordering, (ndianness, =as ta$en from
9ulli#er/s +ra#els by Ronathan 0=ift and refers to the holy =ar bet=een the t=o
em)ires of <illi)ut and -lefuscu about the 9uestion =hich end eggs are to be o)ened at
first.
3he original reference =hich coined the term seems to be a )osting by 7avid !onen in
his famous essay ?"n holy $ars and a plea for peace@, =hich dates from the 1st of
A)ril 185 and became a classic on that subBect after it =as )ublished by the (EEE
com)uting magaKine in 181. 3he article is also $no=n under the reference number
(E&61"7.
Data ordering in little endian mode Data ordering in big endian mode
utsname4!x%!%5s
utsname4!x%!%: sn'6$&
7 utsname4%!%58
utsname4!x%!%: .%6e.6-f%$%&!!!!
7 utsname4%!%5$9
utsname4!x%!%: %$%&!!!! .%6e.6-f
7 utsname4%!%5&x
utsname4!x%!%: ! %$%& .6-f .%6e
7 utsname4%!%58:
utsname4!x%!%: ! ! %& %$ -f .6 6e .%
utsname4!x%!%5s
utsname4!x%!%: sn'6$&
7 utsname4!x%!%58
utsname4!x%!%: .%6e.6-f%$%&!!!!
7 utsname4!x%!%599
utsname4!x%!%: .%6e.6-f %$%&!!!!
7 utsname4!x%!%5&x
utsname4!x%!%: .%6e .6-f %$%& !
7 utsname4!x%!%58:
utsname4!x%!%: .% 6e .6 -f %$ %& ! !
Ehen a )rocessor accesses a multi6byte data ty)e Fi.e. ! ty)es s/ort, int, long,
long longG from memory in a single o)eration, it =ill ma$e an im)licit assum)tion
=hat comes first % the most significant byte F#0-G or the least significant byte F<0-G.
3hese terms are used interchangeably =ith Endianness,
<0- Fleast significant byte firstG / <ittle Endian
16 2.(ntroduction to x86 architectures
Illustration * ! "n the origin of the term 6(ndianness7
Little End
Big End
#0- Fmost significant byte firstG / -ig Endian
As there is endianness on byte level, there>s also endianness on bit level, i.e. regarding
the ordering of bits =ithin a byte. -ut this )oses less )roblems than byte ordering,
because a)art from serial )rotocols little data exchange is done on bit6level, and
fortunately mixed6endian !1*s that used little endian for bits and big endian for bytes
or vice versa Fyuc$ % li$e ancient gree$ =ritten in a mode called ?boustrofedon@, ?li$e
the ox )lo=s@ 6 one line from left6to6right, and the next right6to6leftG are no longer on
the mar$et. 3oday, big6endian !1*s use big endian for both bit and byte ordering, and
li$e=ise little6endian !1*s.
3o a !1*, reading numbers from memory, a$a ordering bytes =ithin a =ord, is li$e
reading a text to humans % =ords are made u) from characters, and you read them
from left6to6right % unless, of course, you>re reading Arabic or Hebre= texts, or
traditional chinese, =here you read them from right6to6left. 3here is no inherent
advantage or disadvantage to do it either =ay, and =hat>s su))osed to be the correct
=ay of doing it de)ends on the !1*;language you use. -ut a conse9uence is that =hat
feels natural to one seems very odd to the other.
0o accessing data the big6endian =ay is li$e reading left6to6right, =hile little6endian is
li$e reading right6to6left and therefore may loo$ odd. -ut if the out)ut is formatted, it
becomes clear again/
/ittle 0ndian1 +ightaligned pointers 2ig 0ndian1 /eftaligned pointers
utsname4#!#/8
utsname4!x#!#: 6%6#6$686%.&6#68
7 utsname4#!#/9
utsname4!x#!#: 6%.&6#68
7 utsname4#!#/x
utsname4!x#!#: 6#68
7 utsname4#!#/:
utsname4!x#!#: 68
utsname4#!#/8
utsname4!x#!#: 6%6#6$686%.&6#68
7 utsname4#!#/9
utsname4!x#!#: 6%6#6$68
7 utsname4#!#/x
utsname4!x#!#: 6%6#
7 utsname4#!#/:
utsname4!x#!#: 6%
3he difference in endianness bet=een e.g. x86 Flittle endianG and 01A2! Fbig endianG
becomes relevant as soon as data is exchanged bet=een t=o machines of differing
endianness. Even =ithin the same system this can ha))en, in the case the !1* and a
)eri)heral device use different endianness but share memory. Ehenever file contents,
shared memory or net=or$ )ac$ets are exchanged bet=een t=o )arties that use
different endianness, a common storage format must be agreed on, or a method to
s=a) endianness must be found.
Exam)les ho= to deal =ith endianness are/
@et$ork Ayte "rdering.
4n creating net=or$ )ac$et contents, the sender is su))osed to use the host6to6
net=or$ interfaces, /tonl01 etc., to convert data to the net=or$ byte ordering,
=hile the receiver shall use the corres)onding net=or$6to6host functions,
nto/l01 etc., to decode net=or$ data into its native format.
&et=or$ byte ordering is big6endian, but it is un)ortable to )rogram based on
that assum)tion. (t>s also unnecessary % on big6endian machines, the interfaces
for host;net=or$ byteorder conversion =ill do nothing % they>ll sim)ly )ass
through their in)ut. !om)iler o)timiKers eliminate these calls on big6endian
systems.
0ee man)age b;teorder0%S<C=ET1.
2emote :rocedure 0alls F21!G.
1assing 21! arguments bet=een t=o systems re9uires an endian6agnostic data
re)resentation. 3his is called +72 Fexchangeable data re)resentationG, and a
2.(ntroduction to x86 architectures 17
library is su))lied that )rograms can use to convert a huge variety of basic data
ty)es into +72 re)resentation. +72 is a generaliKation of net=or$ byte ordering
to arbitrary data ty)es. 0ee man)age xdr0%>S?1.
D)5 )emory 5ccess by device drivers.
1eri)heral devices and the main !1* in a machine may access memory =ith
differing endianness. Ehen =riting a device driver for such a device, the
)rogrammer therefore needs an interface to s)ecify to the host o)erating
system that a given device is big6 or little6endian. 7e)ending on =hether device
and host use the same or a different byte ordering, data to be transferred to or
from that device must be converted into the )ro)er byte order. *nder 0olaris,
the 77( interface set )rovides routines to re9uest byte s=a))ing to be done by
the frame=or$. 0ee man)ages/
ddi6de'ice6acc6attr0*S1, ddi6dma6mem6alloc0*S1 and ddi6dma6s;nc0*S1.
18 2.(ntroduction to x86 architectures
".'.(ar,eteering - .aming the arhitet!re
3he number of trademar$ed and non6trademar$ed terms a))lied to ?x86 !1*s@ and
soft=are that runs on the ?x86 )latform@ is legend, and mar$eting de)artments
every=here $ee) adding to it.
&aming the architecture is truly the -abel of the com)uting industry.
3he term ?x86@ and derivatives of that is generic Fnot trademar$edG, and commonly
used to describe all architectures Fby various vendorsG that =ere in one =ay or the
other ?derived@ from the original (ntel 8586 micro)rocessor, and have a high degree
of com)atibility =ith (ntel !1*s.
3he same a))lies to ?1! com)atible@ 6 though that includes more than Bust a !1*
that is ?x86 com)atible@. 3he original (-# 1!;A3 Ftrademar$ed terms, againG had, in
addition to the i8586 !1*, a set of standard hard=are;)eri)herals =hose )resence
can be assumed on ?com)atibles@. <ater, #icrosoft, (ntel and other hard=are
vendors devised u)dated ?1! ++@ standards to list a set of hard=are;bus interfaces
available by default on ?modern@ systems.
(ntel uses the trademar$ed terms ?(ntel Architecture@, and more s)ecifically ?"2bit
(ntel Architecture@ F(A"2G. (ntel al=ays had more than one !1* architecture in their
)ortfolio Fe.g. today the (tanium;(A6., in the )ast the i865 2(0!, even before that
the i."7G so ?(ntel Architecture@ alone doesn>t mean anything technically. (A"2, on
the other hand, is the term a))lied to the instruction set;feature set of (ntel !1*s
=hose ancestor is the 8586 % in short, (A"2 is ?x86 by (ntel@.
3he !1* names i8586, i85286, i85"86, i85.86, 1entium, ... are (ntel trademar$s.
*&(+ )latforms have traditionally shortened these to i86, i286, i"86 F=ith and
=ithout the leading >i>G. ?"86@ is )articularly fre9uent as the first "2bit version.
?"86@ and variants thereof is found all over/
, file ls
ls: E?@ %$)bit ?S: executable 8!%86 Aersion #"
d;namicall; linked" stripped
2.(ntroduction to x86 architectures 1
Illustration B ! :ieter ArCgel. +o$er of Aabel
, uname )a
Sun<S /atc/back -.#!.# onn')Bork i86pc i%86 i86pc
, isainfo
amd6& i%86
Ee also find it, for exam)le, in the E<C format architecture name/
Cs;s/elf./7: Ddefine EM6%86 % /E Fntel 8!%86 E/
(t>s also )resent as the conditional6com)ile definition for "2bit x86/
Cs;s/isa6defs./7:
2 ... 3
/E
E T/e feature test macro 66i%86 is generic for all processors implementing
E t/e Fntel %86 instruction set or a superset of it. Specificall;" t/is
E includes all members of t/e %86" &86" and Pentium famil; of processors.
E/
Delif defined066i%861 GG defined0i%861
/E
E Make sure t/at t/e H>SF)C Ipoliticall; correctI s;mbol is defined.
E/
Dif Jdefined066i%861
Ddefine 66i%86
Dendif
2 ... 3
(ntel itself never used the terms ?i586@, ?i686@ F=ith or =ithout the >i>G or similar,
but other !1* vendors Fli$e A#7 or !yrixG did, and e.g. the '&* gcc com)iler
recogniKes )m-86 and similar as hint to o)timiKe code for )ost6.86 )rocessors.
3he confusion about names doesn>t get better =ith the extension to 6.bit.
3he 6.bit extension =as created and first s)ecified by A#7. A#7 called this
?x86S6.@ during develo)ment Fand the term is still used as the architecture name on
<inuxG, and ?A#76.@ on release.
(n fact, both are found as the E<C architecture name/
Cs;s/elf./7:
Ddefine EM6HMK6& 6$ /E HMKs x86)6& arc/itecture E/
Ddefine EM698666& EM6HMK6& /E 0compatibilit;1 E/
A#76. a))lies to the instruction set Fx86 including 6.bit extensionsG.
3he A#7 4)teron and Athlon6. are !1*s by A#7 im)lementing the A#76.
architecture.
(ntel for obvious reasons does not use the term ?A#76.@. 0ince ?(A6.@ is already
given to the Fx866incom)atibleG (tanium architecture, (ntel has created t=o ne=
names of its o=n instead/
E#6.3 FExtended #emory 6.bit technologyG
(A"2e
3he first is a))lied to )rocessors by (ntel that are ?A#76. com)atible@, =hile the
second F=hich is very uncommonG is used in (ntel>s architecture reference manual to
describe the 6.bit x86 instruction set FextensionG.
#icrosoft and 0un, for exam)le, chose to use the term ?x6.@ =hen tal$ing about the
6.bit x86 architecture, res). their o)erating systems su))orting it. (n that context,
?x86@ means "2bit6x86, =hile ?x6.@ means 6.bit6x86.
(n this document, the term ?x86@ is used =herever )ossible, =ith a s)ecific note
?"2bit@, ?"2bit mode@, ?6.bit@ etc. as a))ro)riate.
25 2.(ntroduction to x86 architectures
'.#ssembly /ang!age on x86
platforms
Crom ?3he 3ao of 1rogramming@/
+he +ao ga#e birth to machine language.
)achine language ga#e birth to the assembler.
+he assembler ga#e birth to the compiler.
@o$ there are ten thousand languages.
'.1.0eneri $ntrod!tion to #ssembly lang!age
1rogramming languages, ho=ever they are structured, tend to im)lement a common
set of minimum functionality. 1rogramming languages usually have features li$e/
instructions, i.e. o)erations to modify and 9uery LstateL
LstateL Foperands;#ariables;dataG that instructions o)erate on
modulariKation Fthe ability to substructure both )rogram and data into smaller
reusable units of execution;access, termed functions;structuresG
Assembly language of course su))lies all of these. 3he )ur)ose of this section is to
ex)lain ho= constructs used in x86 assembly language im)lement these basic building
bloc$s. 0ince this manual is not su))osed to re)lace introductory tutorials on either
)rogramming in general nor machine6level )rogramming as such, no attem)t =ill be
made to ex)lain things li$e L=hat is an instructionL, L=hat is an ex)ressionL. #inimum
familiarity =ith )rogramming is assumed.
3o understand assembly language )rograms For disassembled com)iled codeG, loo$ at
the above list of language building bloc$s again in more detail.
'.1.1.$nstr!tions
Assembly language uses mnemonics Fhuman6readable transcri)t of the actual binary
machine codeG for instructions. 3he follo=ing classes are usually su))lied/
1. arithmetic;logical instructions. Anything that actually modifies data Fa$a )erforms
an o)erationG falls under this category. Exam)les are addition, multi)lication, and
other numerical o)erations.
2. com)arisons and conditionals to 9uery state and change the flo= of execution
de)ending on that state. A ty)ical exam)le =ould be a Lchec$ if lo=er thanL or a
Lbranch if e9ualL instruction.
". <oad;0tore o)erations for data transfer
.. function subroutine su))ort, a$a call;ret instructions Finstruction transferG
Ho= readable the assembly language for a s)ecific )rocessor is de)ends some=hat on
the choice of the !1* vendor ho= to name the instructions.
(ntel for the x86 !1* family has used )lain english terms For at =orst sim)le
abbreviationsG for assembly instruction names. A ty)ical exam)le =ould be the name of
the instruction that calculates the sum of t=o o)erands/ LHKKL. At =orst, an
abbreviation as LM<A>TLHL F#ove non6tem)oral 9uad=ord alignedG can occur, but in
most cases x86 assembly instruction names are descri)tive.
".Assembly <anguage on x86 )latforms 21
'.1.".Operands1 2ariables and )ata
3o understand the conce)ts used in assembly language for accessing data, =e have to
examine more closely =hat data can be. #ore )recisely, =hat the scope FvisibilityG of a
)articular item is.
4ne )ossible =ay ho= data can be classified in a hierarchical =ay =ould be/
3his is not the only )ossible subclassification of LdataL, of course, but the above
scheme has the advantage that it ma)s very =ell to some of the conce)ts inherent to
assembly language.
Crom the )oint of vie= of currently executing machine code, data can be considered to
be ?closer@ and ?further@ a=ay.
7ata that can be seen from any code =ithin the current )rogram is called global.
'lobal data is )ersistent, it =ill continue to exist even if the s)ecific )iece of code
that ha))ened to be using it has been com)leted.
3he ! )rogramming language $no=s a s)ecific subty)e of global data that is
called static. 0tatic data in ! is not visible to every code from the current
)rogram but only to code from the same sourcefile, or to all instantiations FcallsG
of a given function. ! static also is )ersistent.
Any other data in use by the )rogram is tem)orary and only lives as long as the
current function is executing. 0uch data is recreated;reinitialiKed each time a given
function is run, and different functions o)erate on different sets of data. 3his is
generically called local data. (t is usually subclassed further into/
Cunction in)ut/ 5rguments
Cunction out)ut/ return #alueDsE
4ther non6)ersistent data in use by the function/ local #ariables
0tructured )rogramming languages have finer6grained bloc$s of execution than
functions. !onsider, for exam)le, a loo) =ithin a function. (t uses data, though in
most cases not all of the data that this function is o)erating on. (nstead, it uses only
a subset of that. 3his subset of currently6in6use data is called the $orking set.
Cor o)timal )erformance, a method is desired to access data from the =or$ing set in
22 ".Assembly <anguage on x86 )latforms
Illustration ! Data @amespace based on scope of access
)ata
glob!ll0 *isble *isible 6rom 7it"in
! speci6ic 6#nction onl0
common to !ll
inst!nti!tions
'. l!ng#!ge static)
per 6#nction inst!nce
inp#t
'arguments)
o#tp#t
'return values)
loc!ls
in #se 8 !cti*e
'7or9ing set)
in!cti*e
as fast a =ay as )ossible.
(n terms of machine6level architecture, data as classified above therefore falls into
three big grou)s/
1. 'lobal, )ersistent data. 3his is the Heap.
2. 3em)orary data =hich lives as long as the function that uses it is executing. 3his is
usually called the 1tack.
". 7ata that ma$es u) the current =or$ing set. #ost !1*s )rovide fast6access
tem)orary storage for such data % a set of 2egisters.
".Assembly <anguage on x86 )latforms 2"
Illustration 3 ! )achine!?anguage concepts for heap. stack and registers
H%#P
+%0$ST%+S
ST#C3
in #se 8 !cti*e
'7or9ing set)
common to !ll
inst!nti!tions
'. l!ng#!ge stati)
)ata
glob!ll0 *isble *isible 6rom 7it"in
! speci6ic 6#nction onl0
per 6#nction inst!nce
inp#t
'arguments)
o#tp#t
'return values)
loc!ls
in!cti*e
'.1.'.+egisters1 the Sta, and the Heap
A high6level )rogramming language often does not inherently $no= the conce)t of
memory. Ehere data is stored or ho= it is accessed is u) to the internal
im)lementation of the language and not usually ex)osed to the )rogrammer. Even
intermediate6level languages li$e L!L that su))ly language features for s)ecifying data
locality F! $ey=ords extern;static;auto;register, )ointersG don>t usually s)ecify
ho= these features are im)lemented, but refer to Lthe architectureL to su))ly the
bac$end. Assembly language is different here. 7ue to the tight binding bet=een
hard=are features and assembly language, the )rogrammer here has to $no= about
the details regarding =here data is stored, res). consider the o)timal )lace =here to
)ut o)erands at any given time. 3his is =here the above diagram comes in handy.
Assembly language at least $no=s the distinction bet=een persistent and temporary
data % the heap and the stack. 3here are machines out there Fthe Rava 8irtual #achine,
or Corth, for exam)leG =hich im)lement nothing else, but most current )rocessors
)rovide hard=are su))ort for )utting a $orking set of data into fast tem)orary storage
% a set of registers.
!1* 2egisters are $ind of a L<evel 5 !acheL Fand the existance of registers as a fast6
access tem)orary data storage far )receeds the existance of !1* cachesG =ithin the
!1*, and used to hold variables that are either fre9uently 9ueried or being modified as
)art of a com)utation. (n many !1*s, arithmetic o)erations re9uire the )resence of
the o)erands =ithin registers. !1* registers, )rovided enough of them are available,
=ill be the )lace =here the $orking set of variables for the current function is found.
-ut even modern !1*s created;designed at a time =hen s)ace on the !1* die is
a)lenty, don>t offer unlimited number of registers. 4n the contrary, registers are
usually a scarce resource. 3his is =here the stack comes in again 6 to serve as a
bac$ing store for local variables. -y giving each function its o=n dedicated )iece of
memory s)ecific to this instantiation Fi.e. different for e.g. t=o !1*s calling the same
codeG, a so6called stack frame, the function can Ls=a)L its =or$ing set bet=een stac$
For hea)G and registers.
2egisters and;or the stac$ frame also serve for data6)assing bet=een nested function
calls. -y letting the frames of calling and called function overla), arguments can be
)assed bet=een functions or values returned.
7ata that is not s)ecific to one instantiation of a function call but shared bet=een all
calls to this function Fa ! staticG, or all calls to all functions Fa global variableG =ill
not end u) in the stac$ but in a =ell6defined location in memory that every code $no=s
about. 3his memory location is often called the data segment of the )rogram, or the
heap.
2. ".Assembly <anguage on x86 )latforms
'.".#ssembly lang!age on x86 platforms
'.".1.+egisters
3he general6)ur)ose x86 register set has evolved from the 8bit i8558 )rocessor>s HM;H?
accumulator model via the eight 16bit registers of the i8586 )rocessor, and their
extension Fhence the register name )refix >E>G to "2bit in the i85"86 and 6.bit in the
A#7 4)teron. All registers are global, and 16;8bit register names are only alias names
for lo=er bits of the "2bit register. 3his is called register aliasing. (n "2bit mode, x86
)rocessors im)lement the follo=ing general6)ur)ose registers/
4verall, x86 !1*s in "2bit mode have only eight global, general6)ur)ose registers.
3hey are shared bet=een "2;16;8bit access/
"2bit registers / EH9, E:9, EC9, EK9, ESF, EKF, E:P, ESP
16bit registers / H9, :9, C9, K9, SF, KF, :P, SP
3hese registers cover bit 5..15 of the corres)onding "2bit registers.
8bit registers / H?, :?, C?, K?, and HM, :M, CM, KM,
3hese registers cover bits 5...7 F.?G or bits 8..15 F.MG of registers EH9 ... EK9.
1rocessors in the x86 family su))ly many more registers than that, but none of these
are general6)ur)ose. (nstead, s)ecific instructions are re9uired to ma$e use of those.
!ommonly6seen s)ecial registers in x86 include/
3he )rocessor state registerFsG/ E@?HNS, CO!...CO8.
3he )rogram counter Finstruction )ointerG register/ EFP.
Cloating )oint and vector registers/ ST!..ST8, MM!..MM8, 9MM!..9MM8
1eculiar to the architecture is the conce)t of segmentation, =hich also is controlled via
a s)ecial set of registers/
7escri)tor 3able registers/ NKTO, ?KTO, FKTO
0egment registers/ CS, KS, ES, @S, NS, SS
#odern x86 !1*s su))ly hundreds of registers, all of them s)ecial6)ur)ose. 3hey are
".Assembly <anguage on x86 )latforms 25
Illustration F ! 2egister set Dinteger registersE on %&' architectures in F3bit mode
3
2
b
i
t

r
e
g
i
s
t
e
r
s
1
6
b
i
t

r
e
g
i
s
t
e
r
s
8
b
i
t

r
e
g
i
s
t
e
r
s
%eax
%ebx
%ecx
%edx
%esi
%edi
%ebp
%esp
%ax
%bx
%cx
%dx
%si
%di
%bp
%sp
%ah/%al
%bh/%bl
%ch/%cl
%dh/%dl
called machine!specific registers, or #02, and control s)ecific features of the given
!1*. 1lease refer to the )rocessor manuals from the res)ective !1* vendors.
(n 6.bit mode FA#76. and E#6.3 )rocessorsG, the general6)ur)ose register set is
t=ice as large as before, and access to 16;8bit ?subregisters@ has been unified/
6.bit mode retains register aliasing but ma$es it uniform. (n addition to that, the
number of general6)ur)ose registers Fand the number of 9MM vector registersG has
been doubled. (n 6.bit mode, the !1* )rovides/
16 6.bit registers / OH9, O:9, OC9, OK9, OKF, OSF, O:P, OSP and O8..O#-.
16 "2bit registers / EH9, E:9, EC9, EK9, EKF, ESF, E:P, ESP and O8K..O#-K.
3hese registers ma) bits 5.."1 of the corres)onding 6.bit register.
16 16bit registers / H9, :9, C9, K9, KF, SF, :P, SP and O8P..O#-P.
3hese registers ma) bits 5..15 of the corres)onding "2;6.bit register.
16 8bit registers / H?, :?, C?, K?, KF?, SF?, :P?, SP? and O8:..O#-:.
26 ".Assembly <anguage on x86 )latforms
Illustration * ! 2egister set Dinteger registersE on %&' architectures in '*bit mode
3
2
b
i
t

r
e
g
i
s
t
e
r
s
1
6
b
i
t

r
e
g
i
s
t
e
r
s
8
b
i
t

r
e
g
i
s
t
e
r
s
%eax
%ebx
%ecx
%edx
%esi
%edi
%ebp
%esp
%ax
%bx
%cx
%dx
%si
%di
%bp
%sp
%al
%bl
%cl
%dl
%sil
%dil
%bpl
%spl
%r8d
%r9d
%r10d
%r11d
%r13d
%r12d
%r14d
%r15d
%r8w
%r9w
%r10w
%r11w
%r13w
%r12w
%r14w
%r15w
%r8b
%r9b
%r10b
%r11b
%r13b
%r12b
%r14b
%r15b
6
4
b
i
t

r
e
g
i
s
t
e
r
s
%rax
%rbx
%rcx
%rdx
%rsi
%rdi
%rbp
%rsp
%r8
%r9
%r10
%r11
%r13
%r12
%r14
%r15
3hese registers ma) bits 5..7 of the corres)onding 16;"2;6.bit register.
(n 6.bit mode, the ?highbyte@ registers HM..KM are de)recatedN they still are available
but their use is no longer suggested for 6.bit code.
3he 6.bit x86 register set is uniform % all registers can be used in the same =ay, i.e.
all of them have 8;16;"2bit ?subregisters@. 3hat doesn>t mean all of them are e9ually
efficient, though. 3he x86 instruction set has ?o)timiKed machine o)codes@ for some
arithmetic o)erations that )ut their result into eax;rax, for exam)le. <i$e=ise, the
6.bit extensions encode the use of r8..r#- via an additional byte in the instruction
stream, so the use of the ?classical@ registers vs. the ?ne=@ registers creates more
com)act binary code. 1lease refer to the !1* vendors> o)timiKation guidelines for
instructions on ho= to o)timally use the register set if you intend to =rite assembly
code for 6.bit x86 )latforms manually.
6.bit mode also has the @?HNS register FO@?HNSG, and the 6.bit )rogram counter OFP,
=hich is made ex)licitly available for 1!6relative addressing, a feature not available in
"2bit code.
2egister aliasing re9uires rules that s)ecify ho= the high bits of the 16;"2;6.bit
register are handled if an instruction o)erates ex)licitly on a "2;16;8bit register/
A 8bit o)eration on .? does not affect bits 8.."1 Fi.e. the u))er bits in the .9 and E..
registersG. 4)erating on .M, bits 5..7 and 16.."1 are unaffected.
-its "2...6" of the 6.bit O.. register are cleared.
A 16bit o)eration does not affect bits 16.."1 Fi.e. the u))er bits in E..;O..KG.
-its "2...6" of the 6.bit O.. register are cleared.
A "2bit o)eration clears bits "2..6" of the 6.bit O... register.
(n other =ords, if o)erating in 6.bit mode, all o)erations that are not ex)licitly 6.bit
=ill Kero extend their result to 6.bit. 3he advantage of doing this is in )reserving the
semantics of all existing "2bit o)erations. Cor exam)le, a "2bit addition =ill overflo=
after "2bit and set status register bits to indicate this condition, instead of silently
=ra))ing around to 6.bit and )reventing )ro)er detection of the "2bit overflo=.
".Assembly <anguage on x86 )latforms 27
'.".".#ddressing (odes
Accessing memory is )ossible either/
Direct, su))lying an absolute "2;6.bit value as address
2egister indirect, using the value contained in a register as address
Indirect $ith offset, using the contents of a register as the base address and a Fno
larger than "2bitG constant as additional offset
Indirect $ith inde% and scale, using a register as base address of an array, a second
register as index into that array and a scale factor of 1, 2, . or 8 for that register to
s)ecify the siKe of the elements in the array.
Indirect $ith offset. inde% and scale. 0ame as before, exce)t that no= the start
address of the array =ill be the sum of base register and offset. 3his allo=s e.g. to
efficiently access arrays that are themselves members of larger data structures.
instruction pointer relati#e $ith offset. 3his is only available in 6.bit mode and
allo=s for efficient )osition6inde)endent code.
As a summary, memory access on x86 systems is done by calculating the address
im)licitly using the follo=ing formula/
Any )arts are o)tional. (n "2bit mode, only the "2bit registers eax...esp can be used,
of course.
3he stac$ is s)ecial on x86, and the architecture has ex)licit su))ort for accessing
stac$ memory % via PQSM;P<P instructions.
:ushing something onto the stack =ill decrement esp;rsp by the siKe of the o)erand
and )ut the value of the o)erand into the memory location that esp;rsp )oints at
then.
:opping something off the stack ta$es the value the esp;rsp )oints at, and then
increments esp;rsp by the siKe of the o)erand.
28 ".Assembly <anguage on x86 )latforms
memor0 loc!tion = offset

rax
rbx
rcx
rdx
rsi
rdi
rbp
rsp
r8

r#-

#
$
&
8

rax
rbx
rcx
rdx
rsi
rdi
rbp
rsp
r8

r#-

instruction!pointer!relati#e D'*bit onlyE:


memor0 loc!tion = offset rip
Illustration B ! 1ummary of %&' addressing modes
'.".'.x86 assembly syntax
4n most )rocessors, the assembly language Fi.e. the human6readable mnemonicsG has
been created by the !1* vendor. 3his of course also a))lies to x86, but the story
doesn>t end there. 4n x86 systems, there are t$o dialects of assembly language/
Intel 1ynta%
5+4+ 1ynta%
Cor non6*&(+ assembly )rogrammers, (ntel>s official assembly language syntax =ill be
used. -ut on *&(+ systems, the situation is traditionally reversed. After (ntel released
the 85"86 )rocessor =ith its "2bit ca)abilities, A3T3>s *&(+ 0ystem <aboratories
=ere one of the first o)erating system vendors to create a "2bit o)erating system for
it. 0ince there =as no existing "2bit6x86 mar$et in 185, there =ere also no readily6
available develo)ment toolchains Fcom)iler, assembler, lin$erG for them to use, so this
had to be =ritten, in the case of the assembler from scratch. <egend has it that A3T3
develo)ers loo$ed at (ntel>s assembly language s)ecification and =ere horrified by the
ambiguities in the syntax, and the strong dissimilarity of (ntel>s assembly language
syntax to those of other !1*s that *&(+ had been )orted to before.
0o A3T3 devised their o=n assembly language syntax for x86 )latforms, =hich is
standard for x86 assembly on *&(+ and *&(+6li$e systems.
4n binary level, there>s of course only one x86 machine language. A3T3 and (ntel
0yntax are Bust a different =ay of ma$ing the machine language human6readable. As
an analogy, consider =riting the same chinese6language text =ith chinese characters
and in the )inyin style using latin characters % stri$ing differences, but yet it>s chinese.
Cortunately, the differences bet=een A3T3 syntax and (ntel syntax are smaller than
that.
0ome sim)le exam)les illustrate differences bet=een (ntel and A3T3 syntax very =ell/
Operation A.3. Synta( Intel Synta(
#ove data from
memory into a
register
mo'b address" a/
mo'B address" ax
mo'l address" eax
mo'+ address" rax
M<A HM" 2 address 3
M<A H9" 2 address 3
M<A EH9" 2 address 3
M<A OH9" 2 address 3
#ore Addressing/
7irect, (ndirect,
(ndexed
mo'l address" edi
mo'b )!x$!0ebp1" dl
mo'+ 0rax"rcx1" r#$
mo'l 0edx"esi"&1" edx
mo'B !x80ebp"ecx1" si
mo'B ,!" !x$!0ebx1
mo'l r#$d" #$%&-0rip1
M<A EKF" 2 address 3
M<A K?" 2 E:P R !x$! 3
M<A O#$" 2 OH9 4 OC9 3
M<A EK9" 2 EK9 4 & E ESF 3
M<A SF" 2 E:P 4 EC9 4 !x8 3
M<A P<OK PTO
2 E:9 4 !x$! 3" !
M<A 2 OFP 4 #$%&- 3" O#$K
*se of constants addb ,#!" r#-b
subl ,#$%&" )!x#!0rbp1
orl ,!x#!##!" ebx
xorl ,!xffffffff" ecx
mo'+ ,!x#$%&-6.8*abcdef!" rax
andl ,!xfffffff!" esp
HKK O#-:" #!
SQ: F>T PTO
2 O:P R !x#! 3" #$%&
<O E:9" !x#!##!
9<O EC9" !xffffffff
M<A OH9" !x#$%&-6.8*abcdef!
H>K ESP" !xfffffff!
Arithmetics xorl eax" eax
addl ecx" edx
andl ,!x#!!!" esi
andl ,!x#!" )!x%!0ebp1
9<O EH9" EH9
HKK EK9" EC9
H>K ESF" !x#!!!
H>K F>T PTO
2 E:P R !x%! 3" !x#!
".Assembly <anguage on x86 )latforms 2
Operation A.3. Synta( Intel Synta(
imul+ rax" rbx" rcx
orl ,!x&!!" r#%d
addb ,#$%" global'ar
leal 0eax"eax"&1" eax
leal 0eax"ebx1" ecx
FMQ? OC9" OH9" O:9
<O O#%K" !x&!!
HKK :STE PTO
2 global'ar 3" #$%
?EH EH9" 2 EH9 4 & E EH9 3
?EH EC9" 2 EH9 4 E:9 3
!ontrol transfer
call func9
call Eebx
ret
iret
lcall ,!x$."!
Tae func4!x#$%
CH?? func
CH?? 2 E:9 3
OET
OET @HO
CH?? @HO !" !x$.
8HE func4!x#$%
0)ecial
(nstructions
cmpxc/gl eax" 0ecx1
cmpxc/g+ rdx" 0r#-1
rep(
scasb
pus/al
mo'l xmm-" 0eax"ebx1
lock
orl ,!x8!!" 0rax1
CMP9CMN 2 EC9 3" EH9
CMP9CMN8: 2 O#- 3" OK9
OEPU CHS:
PQSMHK
M<AK 2 EH9 4 E:9 3" 9MM-
?<C= <O F>T PTO
2 OH9 3" !x8!!
(n general, A3T3 syntax has been designed to remove ambiguities that are inherent to
(ntel syntax. 3he differences can be summed u) as follo=s/
A3T3 )refixes register names =ith >> to avoid ambiguities =ith names of variables.
(ntel reserves the names of registers. (f a variable uses a name that the next (ntel
!1* uses for a register % you>re out of luc$.
A3T3 )refixes constants F=hether numerical values or symbols =hose address is to
be ta$en as a constantG =ith >,>.
(ntel does not s)ecifically mar$ constants. Again, ambiguities bet=een register
names and variable names )ossible.
A3T3 orders o)erands source first, destination second, i.e. a from6to ordering.
(ntel uses destination first, source second. 4)erations are ?do to UV/ .@.UV
A3T3 suffixes instruction names =ith b, B, l or + to s)ecify the o)erand siKe.
(ntel derives the o)erand siKe im)licitly from the name of the target register. (n
cases =here the target is memory, the ... PTO syntax extension is used.
A3T3 uses a format offset0base"index"scale1 for address declarations.
(ntel )uts the formula in s9uare brac$ets, 2 :HSE 4 SCH?E E F>KE9 4 <@@SET 3
A3T3 in assembly sourcecode Fnot in disassembler out)ut, thoughG )uts
instruction prefi%es onto se)arate lines.
(ntel re9uires instruction )refixes to directly )receed the instruction they a))ly to.
A3T3 and (ntel name a small set of instructions differently, in cases =here the siKe
suffix in A3T3 syntax ma$es a ne= instruction name unnecessary, for string
instructions, or far calls;returns.
A3T3 by convention uses lo=ercase, and variable names are case6sensitive.
(ntel syntax uses ca)ital letters for everything.
:ee) the differences bet=een A3T3 and (ntel syntax in mind if you>re reading (ntel>s
or A#7>s architecture reference manuals % these all use (ntel syntax. Es)ecially the
"5 ".Assembly <anguage on x86 )latforms
different argument ordering can be confusing at times.
Cor )orting assembly sourcecode =ritten in (ntel syntax to A3T3 syntax, the
?shortcut@ via assembling it using an (ntel6syntax6a=are assembler, and disassembling
it =ith one that out)uts A3T3 assembly is suggested.
As far as this document is concerned, A3T3 syntax =ill be used. 3his is the x86
assembly language found in the 0olaris sourcecode, and the $ind of disassembler
out)ut one gets =hen using debugging tools on the 0olaris o)erating system.
".Assembly <anguage on x86 )latforms "1
'.'.x86 assembly on 4.$5 systems - alling
on&entions1 #6$
3he x86 architecture su))lies instructions for stac$6 and frame)ointer maintenance
and call;ret instructions for )erforming function calls. -ut this is not sufficient. Crom
architectural constraints, no rules exist for/
ho= does the caller pass arguments to the called function J
ho= does the called function return results to the caller J
Ehat ha))ens =ith contents of the FglobalG registers =hen doing a call J
(n addition to that, x86 in hard=are only $no=s basic ! data ty)es c/ar, s/ort, int,
FlongG long, float and double. Ehat about com)ound data ty)es % arrays and
structures J Ho= are these laid out in memory J
!om)iled code should better agree on a common set of rules for )assing arguments
and returning values, for register usage and data structure layout, or else lin$ing code
from a library and a user6su))lied )rogram together is going to brea$ big6time. 3his is
=hy o)erating systems define standard calling con#entions =hich all dynamically6
lin$ed code on this )latform must obey. 3his is called the 5pplication Ainary Interface,
or short A-(.
3he A-( usually is a big document that defines much more than Bust the standard
calling conventions for binary code. 7etails on functions in the standard libraries,
soft=are )ac$aging and installation rules or lists of soft=are )rograms that are
considered an essential )art of the system are also in the A-(.
Cor *&(+ systems derived from A3T3 *&(+ 0ystem 8 2., li$e 0olaris, the relevant
document is the 0ystem 8 A-(. (t contains/
A generic F)latform6inde)endentG )art listing things common to all )latforms *&(+
has been )orted to
A platform supplement )art, cha)ter ", that details the abovementioned )latform6
s)ecific calling conventions and data layout rules for a s)ecific architecture. Ehen
one tal$s about ?the i"86 *&(+ A-(@ or ?the x8666. *&(+ A-(@, =hat>s meant is the
)latform6s)ecific cha)ter " A-( su))lement for the given architecture.
"2 ".Assembly <anguage on x86 )latforms
3o illustrate the calling conventions on x86 systems, =e>ll investigate com)iler6
generated assembly code for a sim)le ! language )rogram/
Dinclude Cstrings./7
/E
E H compound data structure consisting of se'eral primiti'e t;pes
E/
t;pedef struct V
c/ar s6cW
unsigned s/ort s6usW
long s6lW
int s6iW
c/ar s6name2$-63W
struc6t Es6nextW
X struc6tW
/E
E C YconstructorZ for struc6t
E/
int init6struc0
struc6t Es"
c/ar i6c"
unsigned s/ort i6us"
int i6i"
long i6l"
c/ar Ei6name"
struc6t Ei6next1
V
s)7s6c [ i6cW
s)7s6us [ i6usW
s)7s6i [ i6iW
s)7s6l [ i6lW
s)7s6next [ i6nextW
strncp;0s)7s6name"
i6name"
si(eof0s)7s6name11W
return 0#1W
X
(t de)ends on com)iler and o)timiKation ho= the assembly =ill loo$ li$e in the endN the
code belo= =as created using the 0un Eor$sho) com)iler, version 15, on a system
running 0olaris 15. 3he A-( is different for "2bit and 6.bit binaries, as =ill be sho=n.
".Assembly <anguage on x86 )latforms ""
'.'.1.The i'86 4.$5 #6$ - '"bit x86
Cirst, the "2bit assembly code created from the above/
function offset binary opcode assembly , sourcecode
init6struc
init6struc4!x#
init6struc4!x%
init6struc4!x6
init6struc4!x*
init6struc4!xc
init6struc4!xe
init6struc4!x#$
init6struc4!x#6
init6struc4!x#*
init6struc4!x#c
init6struc4!x#f
init6struc4!x$$
init6struc4!x$-
init6struc4!x$b
init6struc4!x%!
init6struc4!x%%
init6struc4!x%6
init6struc4!x%.
init6struc4!x%c
init6struc4!x&#
init6struc4!x&%
init6struc4!x&&
--
8b ec
8% e& f!
8a &- !c
8b &d !8
88 !#
66 8b &- #!
66 8* &# !$
8b &- #&
8* &# !8
8b &- #8
8* &# !&
8b &- $!
8* 8# !c !# !! !!
68 !! !# !! !!
ff .- #c
8% c# !c
-#
e8 fc ff ff ff
b8 !# !! !! !!
8b e-
-d
c%
pus/l ebp
mo'l esp"ebp
andl ,!xfffffff!"esp
mo'b !xc0ebp1"al
mo'l !x80ebp1"ecx
mo'b al"0ecx1
mo'B !x#!0ebp1"ax
mo'B ax"!x$0ecx1
mo'l !x#&0ebp1"eax
mo'l eax"!x80ecx1
mo'l !x#80ebp1"eax
mo'l eax"!x&0ecx1
mo'l !x$!0ebp1"eax
mo'l eax"!x#!c0ecx1
pus/l ,!x#!!
pus/l !x#c0ebp1
addl ,!xc"ecx
pus/l ecx
call Cstrncp;7
mo'l ,!x#"eax
mo'l ebp"esp
popl ebp
ret
... init6struct0
...
1 V
s)7s6c [ i6cW
s)7s6us [ i6usW
s)7s6i [ i6iW
s)7s6l [ i6lW
s)7s6next [ i6nextW
si(eof0s)7s6name1
i6name
\s)7s6name
strncp;0...1W
return 0#1W
X
3he disassembler out)ut is color6coded in the table above to highlight s)ecific areas/
4reen sho=s function prologue and function epilogue.
+ed sho=s ho= init6struc01 acccesses its o=n arguments.
2lue sho=s access to different members of struc6t.
3his sim)le exam)le therefore suffices to demonstrate the rules in the i"86 *&(+ A-(
su))lement.
Ho$ are arguments passed to a function G
Hhere does a function find its o$n arguments G
<oo$ at the call to strncp;01. (ts arguments are pus/l>ed to the stac$, in
reverse order, i.e. arg& )ushed first, arg5 last % immediately before the call.
<i$e=ise, loo$ at the =ay init6struc01 accesses its o=n arguments. 3his is the
code mar$ed red. (ts arguments are found at/
4!x80ebp1 struc6t Es argument 1
4!xc0ebp1 c/ar i6c argument 2
4!x#!0ebp1 unsigned s/ort i6us argument "
4!x#&0ebp1 int i6i argument .
4!x#80ebp1 long i6l argument 5
4!x#c0ebp1 c/ar Ei6name argument 6
4!x$!0ebp1 struc6t Ei6next argument 7
All arguments are )assed on the stac$.
A function locates its arguments based on its frame)ointer.
Arguments, even if smaller than . bytes in siKe, are .6byte aligned on the stac$.
Ho$ does a function return a #alue G
". ".Assembly <anguage on x86 )latforms
!lear enough % the function e)ilogue )laces >1> into register eax.
Ho$ is data in a compound D0 structE laid out. i.e. $hat padding if any is used G
Ee can see from the instructions mar$ed in blue, i.e. those that store the values
)assed as arguments into init6struc01 into the actual struc6t, that the data
structure is laid out so that members can be accessed aligned at a multiple of
their si8e. After the leading c/ar s6c, one byte of )adding ma$es sure that the
follo=ing unsigned s/ort s6us starts at a 26byte aligned address, and so on.
3his is not mandated by the x86 architecture % as =e can see e.g. from the
instruction )ointers, x86 has no generic )roblem =ith misaligned memory
access.
0o far, no thorough ex)lanation of the green stuff, the function )rologue;e)ilogue, has
been given. Ee notice that it saves;restores the caller>s frame)ointer and initialiKes
the one for init6struc01, =hich is needed to ma$e argument access via 4...0ebp1
)ossible, of course, but there>s more to it.
3he )ur)ose of the )rologue becomes clear =hen one loo$s at a significantly more
com)licated function. <et>s ta$e such an exam)le from the 0olaris $ernel, in the form
of the ufs filesystem im)lementation of A<P6NETPHNE01. 3he disassembly starts =ith/
ufs6getpage: pus/l ebp
ufs6getpage4!x#: mo'l esp"ebp
ufs6getpage4!x%: subl ,!x-8"esp
ufs6getpage4!x6: andl ,!xfffffff8"esp
ufs6getpage4!x*: pus/l ebx
ufs6getpage4!xa: pus/l esi
ufs6getpage4!xb: pus/l edi
and the function e)ilogue loo$s li$e this/
ufs6getpage4!x86#: mo'l )!x&80ebp1"eax
ufs6getpage4!x86&: popl edi
ufs6getpage4!x86-: popl esi
ufs6getpage4!x866: popl ebx
ufs6getpage4!x86.: mo'l ebp"esp
ufs6getpage4!x86*: popl ebp
ufs6getpage4!x86a: ret
Ee see that in addition to stac$ reservation and frame)ointer initialiKation, the
)rologue also saves registers ebx, esi and edi to the stac$, =hile the function
e)ilogue restores them before returning to the caller.
3he com)licated function obviously needs to do this because there is a rule that says
?the value in these registers may not to change during call@. Ehich is )recisely =hat
the A-( does % it s)lits the x86 register set into/
2egisters that belong to the caller Fnonvolatile registersG. 3hese are )reserved
during function calls, and the called function, if it uses them, has the obligation to
restore their )revious values before returning. 3he nonvolatile registers are
esp;ebp FobviouslyG and ebx, esi, edi.
1cratch registers. 3hese change their values during function calls % they belong to
the called function, =hich is free to use them for =hatever it =ants Fexce)tion/ it
must )ut its return value into eaxG. 3he scratch registers are eax, ecx, edx.
3his is more com)licated than sim)ler rules li$e ?all registers scratch@ or ?all registers
)reserved@. 0o =hat is the advantage of s)litting the register set into caller!o$ned and
callee!o$ned registers J
".Assembly <anguage on x86 )latforms "5
(t becomes clear if you consider =hat ha))ens in sim)le functions that have no need to
use all registers. 3here are t=o )ossibilities/
a. !om)licated function calling a sim)le function.
(n this case, a rule that says ?all registers scratch@ Fthe caller cannot rely on any
register contents after callG =ould be counter)roductive. 3he sim)le function may
=ell be able to do its tas$ =ithout over=riting registers of the caller.
b. 0im)le function calling a com)licated function.
3his is the other extreme. A rule ?called function must )reserve every register@
=ould no= unneededly re9uire the com)licated function to save and later restore all
registers % although its caller hasn>t even used all of them.
3he designers of the i"86 *&(+ A-( therefore considered it to be beneficial to go the
middle =ay % sim)le functions can get a=ay using only the scratch registers, =hile
com)licated functions =ill never have to save;restore more than the nonvolatile FlocalG
registers.
"6 ".Assembly <anguage on x86 )latforms
'.'.".The #()6* 4.$5 #6$ - 6*bit x86
3he 6.bit *&(+ A-( su))lement for A#76. has been created =hen the 6.bit6x86
<inux )ort =as done. 3here are significant differences =rt. to function calling and
argument )assing bet=een "2bit x86 and 6.bit x86, because the 6.bit A-( attem)ts to
ex)loit the ne= )ossibilities,
16 general6)ur)ose registers
fast 00E2 floating )oint available by default, including 16 +## registers
to s)eed u) function calling.
*nder 6.bit6x86, arguments are passed in registers. Argument )assing therefore
becomes com)licated % for floating )oint arguments, #ery complicated.
3he binary code for the small exam)le turns into the follo=ing 6.bit machine code/
function offset binary opcode assembly , sourcecode
init6struc
init6struc4!x#
init6struc4!x&
init6struc4!x.
init6struc4!xb
init6struc4!xe
init6struc4!x#$
init6struc4!x#6
init6struc4!x#d
init6struc4!x$#
init6struc4!x$&
init6struc4!x$b
init6struc4!x$d
init6struc4!x%$
init6struc4!x%.
init6struc4!x%a
init6struc4!x%b
--
&8 8b ec
&! 88 %.
66 8* -. !$
8* &f #!
&c 8* &. !8
&c 8b &- #!
&c 8* 8. #8 !# !! !!
&8 8% c. #&
&* 8b f#
&8 c. c$ !! !# !! !!
%% c!
e8 !! !! !! !!
b8 !# !! !! !!
&8 8b e-
-d
c%
pus/+ rbp
mo'+ rsp"rbp
mo'b sil"0rdi1
mo'B dx"!x$0rdi1
mo'l ecx"!x#!0rdi1
mo'+ r8"!x80rdi1
mo'+ !x#!0rbp1"r8
mo'+ r8"!x##80rdi1
add+ ,!x#&"rdi
mo'+ r*"rsi
mo'+ ,!x#!!"rdx
xorl eax"eax
call Cstrncp;7
mo'l ,!x#"eax
mo'+ rbp"rsp
pop+ rbp
ret
int init6struc0
...1 V
s)7s6c [ i6cW
s)7s6us [ i6usW
s)7s6i [ i6iW
s)7s6l [ i6lW
i6nextW
s)7s6next [ ...W
\s)7s6name
i6name
si(eof0s)7s6name1
return0#1W
X
3he same color coding as before is used/
4reen sho=s function prologue and function epilogue.
+ed sho=s ho= init6struc01 acccesses its o=n arguments.
2lue sho=s access to different members of struc6t.
(t>s sur)rising to see that the 6.bit code is actually more com)act than the "2bit
version. 3his is due to the changed argument )assing conventions % there is no need to
ex)licitly load arguments from the stac$ into registers % they>re already there.
Cirst, =hat has not changed J
3here>s still a function )ro6 and e)ilogue =hich initialiKes;restores the frame)ointer
for the function. (ts role =ill also be to save;restore the nonvolatile registers.
3he return value is still the same register % no= 6.bit of course, rax.
#embers of com)ound data structures are still being aligned at a multi)le of their
siKe. 0ince A#76. is <16., long is no= 8 bytes and the s6i and follo=ing members
therefore are shifted bac$=ards.
-ut the only access to 4...0rbp1 that =e see is for argument 7. Args 1..6 are )assed
in registers instead/
rdi struc6t Es argument 1
".Assembly <anguage on x86 )latforms "7
sil c/ar i6c argument 2
dx unsigned s/ort i6us argument "
ecx int i6i argument .
r8 long i6l argument 5
r* c/ar Ei6name argument 6
4!x#!0rbp1 struc6t Ei6next argument 7
3his ma$es it difficult to retrieve arguments from call stac$s % they =ill only be )art of
the call stac$ if the called function itself decides to )reserve them. (f not, since all
registers are global, the arguments to a given function =ill be lost as soon as this
function ma$es another call. -esides, before doing that rax is cleared % =hich again
is something that =asn>t done in "2bit.
<i$e on "2bit x86, the 6.bit A-( also s)ecifies ho= registers are shared bet=een caller
and callee. <oo$ing at )rologue/
ufs6getpage: pus/+ rbp
ufs6getpage4!x#: mo'+ rsp"rbp
ufs6getpage4!x&: pus/+ r#-
ufs6getpage4!x6: pus/+ r#&
ufs6getpage4!x8: pus/+ r#%
ufs6getpage4!xa: mo'+ rsi"r#%
ufs6getpage4!xd: pus/+ r#$
ufs6getpage4!xf: pus/+ rbx
ufs6getpage4!x#!: sub+ ,!x*8"rsp
and e)ilogue/
ufs6getpage4!x6b!: mo'l )!x.80rbp1"eax
ufs6getpage4!x6b%: add+ ,!x*8"rsp
ufs6getpage4!x6ba: pop+ rbx
ufs6getpage4!x6bb: pop+ r#$
ufs6getpage4!x6bd: pop+ r#%
ufs6getpage4!x6bf: pop+ r#&
ufs6getpage4!x6c#: pop+ r#-
ufs6getpage4!x6c%: lea'e
ufs6getpage4!x6c&: ret
of a com)licated function again, =e find ho= the register set is used in 6.bit x86 on
*&(+ systems/
rsp and rbp are used for the stack6 and framepointer. 3heir value is )reserved
over function calls FobviouslyG. (f o)timiKed code eliminates the use of a
frame)ointer, rbp becomes a non#olatile register % as in "2bit.
rdi, rsi, rdx, rcx, r8 and r* Fin that orderG are arguments.
A function that uses less than six arguments can use them as scratch registers.
rbx and r#$ through to r#- are non#olatile. 3hey belong to the caller and retain
their values =hen doing a function call. (t>s the called function>s res)onsibility to
save and restore them if it needs them.
rax, r#! and r## are scratch registers. rax contains a return #alue.
"8 ".Assembly <anguage on x86 )latforms
'.'.'.The #()6* 4.$5 #6$ and the register lifeyle
3he big )roblem for )ost6mortem analysis on 6.bit x86 is the argument )assing
conventions/ (f arguments are )assed in global registers, then dee)ly6nested function
call se9uences =ill al=ays have re6used the argument registers of some earlier callers
in the se9uence. 0tac$traces in debuggers on 6.bit x86 therefore usually do not
dis)lay arguments. -ut the =ay registers are being used/
rbx and r#$..r#- are nonvolatile FlocalG % every user of these has the obligation
to save;restore them for its caller
rsp;rbp as stac$6 and frame)ointer
rdi, rsi, rdx, rxd, r8 and r* as argument registers % being re6used =hen the
next function call is made,
rax, r#! and r## as scratch registers
enforces a certain code style that all com)iler6generated assembly code uses.
4n entry, a function/
1. saves rbp of its caller,
2. initialiKes its o=n rbp,
". allocates stac$s)ace by ex)licitly subtracting a value from rsp,
.. saves Fto the stac$G those of the nonvolatile registers rbx, r#$..r#- that it )lans
to use,
5. moves those of its argument registers Frdi, rsi, rdx, rxd, r8 and r*G that it
=ants to use even after ma$ing function calls of its o=n into )ermanent )laces/
into one of the no=6available nonvolatile registers Fi.e. into its local registersG
into ?hidden@ local variables Fi.e. into its stac$G.
4n exit from the function, ste)s 1... are reversed, in order to restore both stac$ and
nonvolatile registers for the caller.
3his code that sets u) Fon entryG and tears do=n Fbefore returnG a stac$frame for a
function is called function prologue ; epilogue. 3he x86 architecture does not su))ly a
single !1* instruction that could be used to im)lement all of the above F01A2! does
all of this im)licitly via register =indo= s=itchesG, so a se9uence of sim)le instructions
is used.
Cor )erformance, the generated code =ill only )erform the necessary o)erations. All of
the above is o)tional in case the given function doesn>t re9uire/
all of the nonvolatile registers Fit>ll only save;restore those that it needsG
stac$ s)ace Fit =on>t allocate stac$s)ace thenG
a frame)ointer Fit =on>t save;initialiKe;restore it thenG
(n addition to that, neither the A#76. nor the i"86 *&(+ A-( s)ecify the exact ste)s
ho= )rologue;e)ilogue code is su))osed to im)lement the ?tas$list@ above. 3he
instructions chosen FM<A vs. PQSM, for exam)leG, the se9uence in =hich e.g. registers
are saved, or =hether registers are saved before or after stac$ allocation is done all
de)ends on the com)iler>s choice and is subBect to com)iler o)timiKation.
3his leads to a multitude of different code se9uences for )rologue;e)ilogue.
1articularly the '&* ! com)iler is creating many different variants, as the follo=ing
exam)les for function )rologue code, all created by gcc, sho=/
".Assembly <anguage on x86 )latforms "
Dense *rologue 5i(ing prologue and
function code
6sing MOV instead of PUSH
pus/+ rbp
mo'+ rsp"rbp
pus/+ r#-
pus/+ r#&
pus/+ r#%
pus/+ r#$
pus/+ rbx
sub+ ,!xd8"rsp
mo'+ rdi")!x&!0rbp1
mo'+ rsi")!x&80rbp1
mo'l edx")!x&c0rbp1
mo'+ rcx")!x-80rbp1
[ ... ]
pus/+ rbp
mo'+ rsp"rbp
pus/+ r#-
mo'l r*d"r#-d
pus/+ r#&
xorl r#&d"r#&d
pus/+ r#%
mo'+ rsi"r#%
pus/+ r#$
mo'l edx"r#$d
pus/+ rbx
sub+ ,!x$8"rsp
cmpl ,!x#!!!"r8d
mo'l edi")!x%c0rbp1
mo'+ rcx")!x&80rbp1
[ ... ]
pus/+ rbp
mo'+ rsp"rbp
sub+ ,!x%!"rsp
mo'+ r#%")!x#80rbp1
mo'+ r#&")!x#!0rbp1
mo'+ rsi"r#%
mo'+ rbx")!x$80rbp1
mo'+ r#$")!x$!0rbp1
mo'+ rdi"r#&
mo'+ r#-")!x80rbp1
[ ... ]
3he 0un Eor$sho) 15 com)iler, as of today, al=ays creates a strict, dense )rologue
similar to the first gcc variant sho=n above. Het, it>s distinctly different in t=o things/
1. Eor$sho)6com)iled code allocates stac$s)ace before saving the nonvolatile
registers,
2. Eor$sho)6com)iled code saves nonvolatile registers in a different order than gcc.
*nli$e gcc, 0un Eor$sho) cc ne#er uses M<A instructions to save the nonvolatile
registers, and it also doesn>t inters)erse code from ?further do=n@ in the function =ith
the )rologue. Eor$sho)6created )rologue code is al=ays similar to something li$e/
.ypical -7bit prologue code created by Sun 8or9shop $:
pus/+ rbp
mo'+ rsp"rbp
sub+ ,!x8"rsp
pus/+ r#$
pus/+ r#%
pus/+ r#&
mo'+ rsi"r#&
mo'+ rdx"r#$
mo'+ rcx"r#%
[ ... ]
3here>s similar variation in function e)ilogue code created by gcc, =hile, again, 0un
Eor$sho) 15 cc al=ays uses a com)act se9uence of pop+ instructions.
(t>s left as an exercise to the reader to familiariKe oneself =ith different styles for
function e)ilogues.
.5 ".Assembly <anguage on x86 )latforms
3his register lifecycle, =ith associated ex)licit function )rologues and e)ilogues that
im)lement it, is due to the register set being global Fshared by everybodyG and the
resulting need to manage register use in a coo)erative =ay. (t>s achieved by moving
registers to the stac$ before using them as ?locals@, and matching that restoring their
values before returning from the function.
As$ing ?=here did a s)ecific register go to@ Fafter entering a functionG or ?=here did a
s)ecific register come from@ Fbefore calling another functionG therefore allo=s us to
trac$ arguments even if register6based calling conventions are in effect, li$e on
A#76..
".Assembly <anguage on x86 )latforms .1
Illustration ' ! 2egister lifecycle I sharing registers. function calling and the stack

Caller' s nonvolat iles


%rbx, %r12 ... %r15

local variables
-...(%rbp)
+...(%rsp)

Caller' s framepoint er %rbp

input argument s
%rdi, %rsi, %rdx,
%rcx, %r8, %r9

out put argument s


%rdi, %rsi, %rdx,
%rcx, %r8, %r9

nonvolat iles (locals)


%rbx, %r12 ... %r15

Caller' s nonvolat iles


%rbx, %r12 ... %r15

local variables
-...(%rbp)
+...(%rsp)

Caller' s framepoint er %rbp

Caller' s nonvolat iles


%rbx, %r12 ... %r15

local variables
-...(%rbp)
+...(%rsp)

Caller' s framepoint er %rbp

input argument s
%rdi, %rsi, %rdx,
%rcx, %r8, %r9

out put argument s


%rdi, %rsi, %rdx,
%rcx, %r8, %r9

nonvolat iles (locals)


%rbx, %r12 ... %r15

input argument s
%rdi, %rsi, %rdx,
%rcx, %r8, %r9

out put argument s


%rdi, %rsi, %rdx,
%rcx, %r8, %r9

nonvolat iles (locals)


%rbx, %r12 ... %r15
R
e
g
i
s
t
e
r

S
e
t
S
t
a
c
k

G
r
o
w
t
h
'.*.Case st!dy7 Comparing x86 and SP#+C assembly
lang!ages
3he t=o )latforms currently su))orted by the 0olaris o)erating system are 01A2! and
x86. As already sho=n, 01A2! is a 2(0! architecture =hile x86 is !(0!. 3his alone
doesn>t sum u) all of the differences bet=een the t=o assembly languages, of course/
;eature <o= ('- does it <o= S*A+, does it
instruction length varies from 1..16 bytes.
3he instruction )ointer usually
is misaligned.
constant . bytes.
#isaligned )rogram counters
cause tra)s.
general!purpose
registers
all registers are global.
eight in "2bit, sixteen in 6.bit.
A-( determines register usage.
"2 registers, 8 each are
global;in)ut;local;out)ut.
2egister =indo=s =ith the idea
of out)ut;in)ut overla) are
inherent in 01A2! architecture.
dedicated
/de#/null register
&one. (t>s unnecessary.
x86 has )lenty of s)ecial6case
instructions that ma$e
discarding a result unnecessary,
and the ability to embed Kero as
a constant into any instruction.
2egister g! discards =rites and
al=ays reads as Kero.
Cre9uently used if the result of a
calculation is unnecessary and
only the effect on condition
codes is relevant, i.e. in
synthetic instructions li$e cmp.
stack! and
framepointer
3he architecture mandates the
use of register esp;rsp as
stac$)ointer, and suggests using
ebp;rbp as frame)ointer.
#any instructions im)licitly
o)erate on the stac$.
3he register =indo=ing
mechanism =ould su))ort the
use of any )air i.;o. as
stac$;frame)ointer.
-y convention, i6;o6 are used
for frame;stac$)ointer.
arithmetic/logical
instructions
x86 arithmetic ; binary logical
instructions are destructi#e %
the second source o)erand =ill
be over=ritten =ith the result.
x86 im)lements the ! language
a 4[ b
style.
01A2! arithmetic ; binary
logical instructions are usually
nondestructi#e. All instructions
ta$e three registers % t=o for
the source o)erands and one for
the destination o)erand. (n !/
a [ b 4 c.
memory operands x86 allo=s one memory o)erand
)er FarithmeticG instruction.
Either source or destination can
be memory. (nstructions
modifying memory =ithout
involving a register are )ossible.
01A2! can only modify data in a
register. 3o modify a =ord in
memory, a load!store cycle Fload
it from memory to a register,
change it in the register, store it
bac$G is re9uired.
implicit register
usage
#any instructions im)licitly
modify certain registers/
stac$;frame)ointer changed by/
call;ret
pus/;pop
enter;lea'e
string instructions/
01A2! instructions re9uire an
ex)licit destination register.
(n cases =here this is not
sho=n, the instruction is
synthetic and the destination is
ex)licit from that, usually g! if
the result is irrelevant. &otable
exce)tion is call;ret, =here
.2 ".Assembly <anguage on x86 )latforms
;eature <o= ('- does it <o= S*A+, does it
ta$e source;destination from the
string source;dest registers
esi;edi F"2bitG, rsi;rdi
F6.bitG
counted loo)s, re)eat )refixes/
ecx;rcx holds counter value
6.bit arithmetics in "2bit mode/
edx/edx hold 6.bit value.
o.;i. are used to hold the
return address.
instruction!
embedded
constants
Cor direct addressing and
initialiKation Fmo'+ instructionG,
constants u) to 6.bit are
)ossible.
All other instructions allo=
using "2bit constants directly.
(nstruction6embedded constants
cannot be larger than 1" bit
Fincluding the signG.
Cor initialiKation, the set/i
instruction allo=s to )ut a 1bit
value into bits "1..1" of a
register.
<arger constants are
constructed in a se9uence of
set/i;or.
atomic
instructions
x86 $no=s e%plicit atomicity via
the lock instruction )refix.
Every instruction that allo=s a
memory location as target
o)erand can be made atomic.
01A2! has a dedicated set of
instructions that are implicitly
atomic: cas, ldstub, or xc/g.
4thers need to be ?emulated@
using these.
illegal/undefined
instructions
'enerically, none. 2andom data
translates into ?meaningful@
instruction se9uences for x86.
x86 $no=s ?the@ undefined
instruction, ud$, a reserved
o)code that triggers a tra).
<ots of.
Eide ranges for the o)code bits
in the "2bit instruction are not
assigned a s)ecific meaning
Filltrap and undefG and cause
tra)s.
5ddressing x86 addressing modes/
7irect F6.bit absolute addressG
(ndirect Faddress in a registerG
(ndirect =ith 8;16;"2bit offset
(ndexed Faddress D scaleWindexG
and combinations of those.
(n 6.bit mode, it can also do/
)osition6relative F1! )lus offsetG
01A2! addressing modes/
(ndirect
(ndirect =ith index
(ndirect =ith 1"bit offset
4n 01A2!, addressing is al=ays
indirect % an address must be in
a register before ld;st.
(ndirect =ithout FAG index is
done using g! as index ...
3he total number of instructions on x86, given that it>s !(0!, is of course much higher
than on 01A2!, being a classical 2(0! architecture.
".Assembly <anguage on x86 )latforms ."
A)art from these architectural differences bet=een the assembly languages, there are
differences to the A-( =rt. to ho= function calling =or$s % =hich, from the )oint of
vie= of )ost6mortem analysis, mostly affect layout and contents of the stac$.
!om)aring )ro)erties of the stac$ on x86 and 01A2!/
stac9 detail <o= ('- does it <o= S*A+, does it
function
arguments
"2bit x86 )asses all arguments
on the stac$. A debugger can
al=ays retrieve them.
6.bit x86 )uts the first six args
to rdi, rsi, rdx, rcx, r8,
r* and s)ills arguments after
that into the stac$. args 1..6 can
only be retrieved from the stac$
if the called function saves them
to the stac$ ex)licitly.
01A2! )uts the first six args
into o!..o-, =hich after the
sa'e done by the called function
are then found in i!..i-.
A register =indo= flush at a
later time =ill =rite these into
the stac$ and a debugger can
retrieve them from there, but an
in)ut register could>ve been
reused.
Arguments )ast the sixth s)ill
onto the stac$, li$e 6.bit x86.
return addresses 3he x86 call instruction )ushes
the address of the instruction
follo=ing it Fi.e. the actual
return addressG onto the stac$.
3he x86 ret instruction )o)s off
the return address and Bum)s
there.
3he 01A2! call instruction
)uts its o=n FAG address into i..
3he 01A2! ret instruction is
synthetic % it =ill evaluate to
Tmp 2o.483 Fs$i))ing the delay
slot of callG. *sing a restore
as delay slot for ret resets the
register =indo= for the caller.
2eturn addresses are =ritten to
the stac$ =hen a register
=indo= flush occurs.
sa#ed
framepointers
x86 re9uires ex)licit stac$ frame
maintenance, both on entry/
pus/l ebp
mo'l esp"ebp
subl ..."esp
or, as ?abbreviation@ for these/
enter ...
and on exit from a function/
mo'l ebp"esp
popl ebp
or, again as a single instruction/
lea'e
3he use of a frame)ointer is
o)tional % it can be o)timiKed
a=ay.
call =rites the return address
to the stac$ before the called
function saves the frame)ointer.
3he stac$ therefore has )airs of
return address;frame)ointer.
01A2! gives frame)ointer
maintenance for free via the
register =indo=ing mechanism.
A function on entry reserves
stac$s)ace via/
sa'e i6"..."o6
and thereby also )erforms the
=indo= s=itch Fne= i6 X old
o6, and ne= o6 X old o6
minus frame siKeG. sa'e is
e9uivalent to the ex)licit stac$6
;frame)ointer dance on x86.
3o undo the =indo= s=itch and
restore the caller>s stac$6 and
frame)ointer, a function =ill call
restore on return.
0tac$6;Crame)ointer i6;o6
are flushed on =indo= s)ill.
2eturn addresses are in i.;o.
and the stac$ therefore has
.. ".Assembly <anguage on x86 )latforms
stac9 detail <o= ('- does it <o= S*A+, does it
)airs
frame)ointer;return address.
stackspace usage x86 stac$s are dense.
Cunctions that can do all their
=or$ using their arguments and
the available scratch registers
=ill not allocate stac$s)ace at
all. A stac$ se9uence =here t=o
return address;frame)ointer
)airs follo= each other =ithout
anything in6bet=een is common.
01A2! stac$s are sparse.
0tac$frames on 01A2! are at
least MF>@OHME siKe % to )rovide
bac$ing store for the 16 ne=
registers >allocated> by the
register =indo= s=itch. Even a
function that doesn>t use all of
its i.;l.;o. registers must
allocate bac$ing store for them.
3he minimum distance bet=een
frame)ointer;return address
)airs therefore is MF>@OHME.
stack bias x86 stac$6 and frame)ointers
are not biased, neither in "2bit
nor in 6.bit mode.
A x86 !1* has other means of
detecting the o)erating mode
than deriving that from =hether
the stac$)ointer is misaligned or
not. 0ee cha)ter ".
01A2! 6.bit stac$)ointers are
biased % offset by !x.ff, and
therefore al=ays misaligned.
3he 01A2! $ernel uses this for
t=o )ur)oses/
1. 3o distinguish bet=een "2bit
and 6.bit a))lications in tra)
and system call handlers.
2. 7ue to the address offset siKe
limitation, !x.ff, biased
stac$s allo= 6.bit code on
01A2! to access stac$frames
t=ice the siKe =ithout ex)licit
offset calculations.
".Assembly <anguage on x86 )latforms .5
'.8.The role of the sta,
4n 2(0! architectures =ith huge numbers of registers, assembly6level )rogrammer
and;or engineers doing lo=6level troubleshooting and crash6;coredum) analysis often
can ignore the stac$ % everything interesting is in registers, the stac$ is )urely bac$ing
store and the debugging tools ?Bust dis)lay@ arguments or local variables for a given
function in the bac$trace. 3his is es)ecially true on 01A2!, =here the register =indo=
architecture ma$es this a))roach comfortable and easy % the debugger finds me the
register =indo= and ( =ill then only loo$ at the registers of a s)ecific function.
3his is not so on x86 )latforms. 3he scarcity of registers forces functions to allocate
stac$ s)ace for local variables. (t has already been sho=n that at least in "2bit mode,
even argument )assing is done via the stac$. (n 6.bit, =here arguments are )assed in
registers, they may indirectly a))ear on the stac$ % the called function often has to
save them into ?hidden locals@ on its stac$frame to )reserve them for the case that it
needs the arg registers for doing another call itself.
All this ma$es ex)licit stac$ accesses the most6fre9uent o)eration x86 machine code
=ill do. 0tatistics illustrate this. 3he follo=ing shellscri)t/
DJ/bin/ks/
functions[,0
ec/o Y::nm )t func )f nameZ G mdb )k G sort )u G aBk ]V if 0>O 7 #1 print X]
1
for fnc in ,functionsW do
asmcode[,0ec/o Y,fnc::disZ G mdb )k1
linestotal[,0ec/o Y,asmcodeZ G Bc )l1
stackaccess,0ec/o Y,asmcodeZ G egrep ]2re32bs3pGpus/Gpop] G Bc )l1
ec/o Y,fnc ,linestotal ,stackaccessZ G
aBk ]V printf0Ys d d $.$f^nZ" ,#" ,$" ,%" #!!E,%/,$1 X]
done $7/de'/null
allo=s to create a table =hat )ercentage of the instructions in 0olaris $ernel functions
is an ex)licit stac$ access. 3his gives/
3he result, averaged over every function in 0olaris 15;x86 6.bit, is a =ho))ing 2"Y %
=o=. Almost every fourth instruction on average is a stac$ access A
.6 ".Assembly <anguage on x86 )latforms
Illustration J ! stack access by K3BLLL functions in 1olaris L/amd'*
0 5 1
0
1
5
2
0
2
5
3
0


3
5
4
0
4
5
5
0
5
5
6
0
6
5
7
0
7
5
8
0
8
5
9
0
9
5
1
0
0
0
200
400
600
800
1000
1200
percent!ge o6 6#nction code !ccessing t"e st!c9
n
#
m
b
e
r

o
6

6
#
n
c
t
i
o
n
s
Cor a "2bit $ernel, due to the fact that argument )assing there is done on the stac$ as
=ell, =e ex)ect even higher figures. 8erifying this is left as an exercise to the reader A
Eor$ing =ith x86 assembly code, and even more so doing )ost6mortem debugging on
x86 )latforms therefore re9uires a thorough understanding of the stac$. Ee have to
become, literally, able to identify each and every value in a given stac$ to reconstruct
=hat has been ha))ening in this function call se9uence.
'.8.1.Sta, basis
0tac$ access can be implicit or e%plicit in x86.
(m)licit stac$ access is done by instructions that modify the stac$)ointer and;or
contents of the stac$ =ithout re9uiring stac$6 or frame)ointer as argument % ty)ically
PQSM or P<P. 3his is the classical stac$ % a ?IF" Flast in first outG array.
A ! language ty)e declaration for using a stac$ =ould loo$ li$e this/
'oid Estackpointer23W
Ddefine PQSM0'alue1 E0))stackpointer1 [ 0'oid E1'alue
Ddefine P<P0'alue1 'alue [ E0stackpointer441
3he stac$ by convention gro$s do$n$ard. 0ubtracting something from the
stac$)ointer therefore means stac$s)ace is being allocated, and vice versa adding to
the stac$)ointer frees stac$s)ace. PQSM and P<P do that im)licitly % allocate;free one
=ord of stac$s)ace and )ut;get the argument FfromG there.
x86 has pus/l F"2bitG;pus/+ F6.bitG and the corres)onding popl;pop+ instructions, it
im)lements a stac$ as sho=n above in hard=are. pus/;pop are extremely common
o)erations. (n addition to these basics, x86 has several im)ortant instructions =hich
)ush;)o) values im)licitly and do something =ith it. 0uch instructions also come in
)airs, li$e pus/ and pop.
3he first )air is call and ret. 3hey are used to )erform function calling.
call transfers execution and saves information for the called function =here to
return to once its =or$ is done. 3he return address Faddress of the instruction
follo=ing callG is )ut % on the stac$. call therefore is e9uivalent to FnonexistantG
)seudocode/
PQSM CF>STOQCTF<> P<F>TEO 4 si(eof0call instrunction17
N<T< CCH?? THONET7
ret of course is the o))osite % the called function uses this =hen it>s done, in order
to resume the caller. 'iven ho= call =or$s on x86, )seudocode for ret must be/
P<P COETQO> HKKOESS7
N<T< COETQO> HKKOESS7
3he other )air, enter;lea'e, is also related to code modulariKation;function calling. 3o
ex)lain =hat exactly these do, =e need to go into the details of modulariKation again %
ho= does nested function calling =or$, and =here do function )ut their data J
(t =as already mentioned that the stac$ can be used by functions in lo=6level code to
hold transient data % arguments, local variables and return values. 0ince for obvious
reasons t=o functions don>t share local variables, that means every function in a
calling se9uence must get its o=n dedicated )iece of stac$s)ace % the stack frame of
this function. (t is convenient to let stac$frames of caller;callee overla) % for )assing
data bet=een t=o functions, if re9uired. 01A2! register =indo=s =ith out)ut;local;
in)ut registers use this model for registers, but in a more rigid version Ffixed siKe
framesG than ?generic stac$s@. 0tac$s therefore generically loo$ li$e this/
Eith a stac$)ointer6only model, the running function only $no=s the end of its stack %
".Assembly <anguage on x86 )latforms .7
but has no direct $no=ledge of =here its stac$frame starts. (t can go the hard =ay and
count For let the com)iler count during code generationG ho= many items it has on the
stac$ at a )articular )oint % or it $ee)s a record of =hat the stac$)ointer =as at entry
to the function, by recording the start of its stackframe. 3his is called framepointer.
0tac$6 and frame)ointer s)ecify =here a stac$frame starts and =here it ends.
3he framepointer locates the start of the last stac$frame.
3he stac9pointer records the location of the last item on the stac$.
0ince a frame)ointer is nice to have, x86 )rovides a )air of instructions enter;lea'e
that functions may use on entry;exit to allocate;free stac$s)ace and s=itch
frame)ointer and stac$)ointer.
enter is e9uivalent to the follo=ing se9uence of sim)le instructions F"2bit sho=nG/
pus/l ebp save )revious frame)ointer
mo'l esp"ebp ne= frame)ointer/ stac$)ointer at entry
subl ,..."esp allocate stac$s)ace.
(t>s uncommon to see com)iler6generated code that uses enter % both A#7>s and
(ntel>s 4)timiKation 'uidelines de)recate this instruction in favour of the sim)le
se9uence sho=n.
lea'e is e9uivalent to the follo=ing se9uence of sim)le instructions F6.bit sho=nG/
mo'+ rbp"rsp free stac$s)ace
pop+ rbp restore )revious frame)ointer
(t de)ends on the com)iler =hether it uses lea'e or the sim)le se9uence % both are
commonly found.
3hese are the common x86 instructions that im)licitly access the stac$. -ut stac$6 and
frame)ointer both are registers Fesp;rsp/ stac$)ointer, ebp;rbp/ frame)ointer, in
"2;6.bit modeG, and therefore usable =ith any of the x86 addressing modes to locate
data on the stac$. (%plicit stac$ access via stac$6 or frame)ointer6indirect addressing
therefore has the advantage of locating any item on the stac$ directly % not Bust the
to)most one as PQSM;P<P.
.8 ".Assembly <anguage on x86 )latforms
Illustration & ! stack layout
stac$)ointer at start
"rame 1
st
"unction
"rame 2
nd
"unction
"rame 3
rd
"unction
"rame #
th
"unction
"rame 5
th
"unction
stac$ gro=th,
more function
calls
current stac$)ointer
overla))ing frames
F)assing data bet=een functionsG
f
u
n
c
t
i
o
n

c
a
l
l
n
e
s
t
i
n
g

l
e
v
e
l
'.8.".Sta, ontents in detail
Crom all information given so far, =e can no= refine the )reviously6sho=n )icture
about stac$ usage so that it fully reflects the situation on x866based *&(+ systems.
Cindings/
0ince call is used to transfer instruction to another function, a return address =ill
be on the stac$.
0ince the ne= function =ill save the caller/s framepointer on entry, it =ill be on the
stac$.
0ince the ne= function li$ely allocates stac$s)ace, some ?other@ data =ill follo=.
3hese values can be locals, saved nonvolatile registers, or Fin 6.bit modeG saved
argument registers. Ehat exactly is in there and =hether this ?other@ data exists
de)ends on that function.
(f another function is being called, arguments may be )ut onto the stac$.
All this combined gives the follo=ing stac$ layout diagram for x86 )latforms/
#atching this to real stac$ data from core6 and crashdum)s on 0olaris;x86 =ill be
ex)lained in all details in cha)ter 6.
'.8.'.#d&aned7 6!ffer o&erflow exploits
&ot sure % shall ( include this J
".Assembly <anguage on x86 )latforms .
Illustration M ! %&' stack layout details
stac$)ointer at start
"rame 2
nd
"unction
"rame 3
rd
"unction
"rame #
th
"unction
"rame 5
th
"unction
stac$ gro=th,
more function
calls
f
u
n
c
t
i
o
n

c
a
l
l
n
e
s
t
i
n
g

l
e
v
e
l
r
e
t
.

a
d
d
r
e
s
s

t
o

f
u
n
c
.

4
r
e
t
.

a
d
d
r
e
s
s

t
o

f
u
n
c
.

3
r
e
t
.

a
d
d
r
e
s
s

t
o

f
u
n
c
.

2
r
e
t
.

a
d
d
r
e
s
s

t
o

f
u
n
c
.

1
s
a
v
e
d

f
r
a
m
e
p
t
r

f
u
n
c
.

4
s
a
v
e
d

f
r
a
m
e
p
t
r

f
u
n
c
.

3
s
a
v
e
d

f
r
a
m
e
p
t
r

f
u
n
c
.

2
s
a
v
e
d

f
r
a
m
e
p
t
r

f
u
n
c
.

1
a
r
g
s

t
o

f
u
n
c
.

5
a
r
g
s

t
o

f
u
n
c
.

.
a
r
g
s

t
o

f
u
n
c
.

2
"rame
1
st
"unction
)assing
arguments/
end of caller>s
frame
current
stac$)ointer
current
frame)ointer
'.6.Odd things abo!t the x86 instr!tion set
3al$ about things li$e ?EH, OEP, ?<<P, ... J Cloating )oint and ##+;00E J
55 ".Assembly <anguage on x86 )latforms
'.9.%xamples of ompiler:generated ode on x86
platforms
(n order to give the reader a better im)ression =hat to ex)ect =hen loo$ing at
disassembled )rogram code, this section =ill )rovide exam)les of com)iler6generated
assembly from ty)ical ! language constructs/
function calling, argument )assing, argument access
if 0...1 V ... X else V ... X statements
sBitc/ V ... X statements
for 0...1 loo)s
accessing data structures and arrays.
Ee =ill also chec$ ho= the binary code for data access changes if the com)iler is
instructed to create position!independent code.
Exam)le sourcecode and resulting com)iled code =ill be given for "2bit and 6.bit.
'&* gcc and 0un Eor$sho) 15 com)ilers are used to illustrate com)iler differences.
'.9.1.x86 instr!tions !sed by S!n ;or,shop < 0.4 C
Compilers
4verall, com)iled code on x86, =hether "2bit or 6.bit, uses far fe=er instructions than
one could ex)ect given the Z1555 different ones that the instruction set )rovides. As
already indicated before, efficient )rogramming on x86 means using the chi) li$e it
=ere 2(0!, and restrict oneself to a set of ?fast)ath instructions@. -ut =hat are those J
3his diagram has been created by iterating over the symbol table of a "2bit 0olaris;x86
crashdum) and disassembling every function. (n total, 168125 instructions =ere
found and then binned by instruction name % the gra)h sho=s the result.
0ince the 0olaris 15 $ernel is a )retty large )iece of code Falbeit integer onlyG, =e can
assume =ith a good level of confidence that the distribution of ho= fre9uent certain
instructions are being used here is re)resentative of =hat =e can ex)ect in any large
com)iler6generated binary.
<et>s loo$ at the same histogram as sho=n before, but no= generated from a 6.bit
".Assembly <anguage on x86 )latforms 51
Illustration L ! *L most!used instructions in the F3bit 1olaris/%&' kernel
0
o
t
/
e
r
s
1
s
b
b
l
T
a
e
s
a
r
l
m
o
'
s
B
l
T
a
a
d
c
l
s
t
c
T
g
t
e
s
t
b
T
b
e
T
l
e
T
b
i
m
u
l
l
s
/
r
l
T
l
d
e
c
l
s
/
l
l
c
m
p
b
m
o
'
(
b
l
m
o
'
B
m
o
'
(
B
l
o
r
l
i
n
c
l
m
o
'
b
s
u
b
l
n
o
p
a
n
d
l
x
o
r
l
l
e
a
l
T
m
p
r
e
t
T
n
e
t
e
s
t
l
c
m
p
l
T
e
p
o
p
l
c
a
l
l
a
d
d
l
p
u
s
/
l
m
o
'
l
0+1:
1:
10:
100:
Solaris 10/x86 32bit, instruction usage in % of total
0olaris 15;x86 $ernel. !reated as before % by disassembling all function symbols from a
6.bit 0olaris;x86 crashdum). (n total, 17556"7 instructions =ere found.
3his not only differs in "2bit vs. 6.bit, but also sho=s ho= different com)ilers can
change the set of instructions used in com)iler6generated binary code % the 6.bit
0olaris 15 $ernel is com)iled using gcc "...".
0ome ex)lanation of these gra)hs and of course the sho=n fre9uently6used
instructions is in order.
Cirst, =e note in both "2bit and 6.bit modes, mo' Fin all its siKesG is the by6far most6
fre9uently used instruction. 3his has several reasons/
mo' is multi6)ur)ose. (t can/
copy a register into another,
initiali8e a register or memory =ith a constant,
do memory loads and stores.
4ur statistics for stac$ access have already sho=n that almost M
th
of all code in
6.bit Fand as mentioned even more in "2bitG does im)licitly or ex)licitly use the
stac$. &ot all of this is going to be pus/;pop % some significant amount =ill be
ex)licit stac$ access via mo'.
!onsidering the stac$ brings us to other im)ortant instructions. Ee note that on "2bit,
pus/l and addl are 2
nd
and "
rd
)lace =hile their 6.bit cousins pus/+;add+ are much
less fre9uent. 3he reason for this again is the A-( difference % "2bit code )asses
arguments on the stac$ and uses pus/l to do so. After returning from call, addl is
FoftenG used to clean u) the stac$ Fi.e. )o) off the arguments into ?no=here@G. 4n
6.bit, neither is necessary unless there are more than six arguments % so the
remaining use for pus/+;pop+ that no= dominates their usage is the function )rologue.
3he ratio of 6.bit pop+ vs. pus/+ is much closer than the one for "2bit pus/l vs. popl.
3he next big contributors are of course call;ret;lea'e, and as indicated pus/;pop as
)art of function )ro6 and e)ilogues. 3he fact that the "2bit code doesn>t seem to use
lea'e highlights a com)iler difference % as the disassembly exam)les later in this
cha)ter =ill sho=, gcc tends to use lea'e in e)ilogues =hile Eor$sho) cc uses the
e9uivalent sim)le instruction se9uence, and the "2bit code =as com)iled using
Eor$sho) cc, =hile the 6.bit code is gcc6created.
Another big )art of code is anything related to branching % cmp and test in all siKes,
52 ".Assembly <anguage on x86 )latforms
Illustration ! *L most!used instructions in the '*bit 1olaris/%&' kernel
0
o
t
/
e
r
s
1
i
n
c
+
T
b
e
T
g
a
d
d
l
s
e
t
n
e
l
e
a
l
s
e
t
e
d
e
c
l
s
/
l
+
T
a
T
l
e
m
o
'
B
c
m
p
b
m
o
'
(
B
l
o
r
l
m
o
'
b
i
n
c
l
m
o
'
s
l
+
a
n
d
l
m
o
'
(
b
l
s
u
b
+
t
e
s
t
b
a
d
d
+
c
m
p
+
l
e
a
'
e
r
e
t
t
e
s
t
+
p
o
p
+
c
m
p
l
l
e
a
+
p
u
s
/
+
n
o
p
t
e
s
t
l
T
n
e
x
o
r
l
T
m
p
T
e
c
a
l
l
m
o
'
l
m
o
'
+
0+1:
1:
10:
100:
Solaris 10/x86 64bit, instruction usage % of total
the different conditional branches T.., and Tmp as unconditional goto. &ot every code
se9uence can be streamlined, of course. &ote that in 6.bit mode, =e more fre9uently
use cmpl and testl than their 6.bit cousins % =hich sho=s the code doesn>t use 6.bit
o)erand siKe that often Fexce)t for )ointers, of courseG, and )roves A#7 =as right in
ma$ing "2bit o)erand siKe the default even =hen running in 6.bit mode. cmpl;testl
use less code s)ace and more efficient in execution than cmp+;test+.
3hen, there>s xorl % in both "2bit and 6.bit. Ee see much more xorl o)erations than
any other arithmetic;logical instruction. Ehy on earth should =e xor things so often J
Eell, =e don>t. -ut there>s one )eculiar xorl o)eration that>s very handy, and that is to
xor a register =ith itself % 8eroing it. 7ue to Kero6extension for "2bit o)erations, that
even =or$s in 6.bit mode. 3he same instruction, xorl eax"eax Keros eax in "2bit
and rax in 6.bit mode. 01A2! has g!, x86 has xorl.
3he next )eculiar thing is the lea instruction Fleal and lea+G. lea stands for load
effecti#e address, but its name not=ithstanding this is no memory access. lea does
address calculation. (t )erforms )ointer arithmetics, if you li$e. 3he difference
bet=een
leal 4!x#!0eax"ecx"81" esi
mo'l 4!x#!0eax"ecx"81"esi
is the same as the difference bet=een ! code that does something li$e/
'araddr [ \m;struct)7arra;2i3W
'arcontents [ m;struct)7arra;2i3W
(n other =ords/ lea is an arithmetic o)eration % it ta$es the address s)ecification as a
formula and calculates the result =ithout actually attem)ting to dereference. lea can
Fand =illG be used for general6)ur)ose arithmetics, as long as the desired com)utation
can be ex)ressed =ithin the bounds of =hat x86 addressing modes allo=.
Collo=ing this is nop Fand in "2bit code andlG. -oth are for o)timiKation % =hile x86
!1*s don>t re9uire instruction For stac$6G )ointer alignment, they may )erform better
in some situations if code or stac$ are aligned at e.g. multi)les of 16. -oth com)ilers
are a=are of this and therefore generate the necessary code.
Ehat remains in the sho=n diagrams falls into t=o classes of instructions/
arithmetics of all sorts. add, adc Fadd =ith carryG, sub, sbb Fsubtract =ith borro=G,
inc, dec, imul, or, and, s/r;s/l res). sar;sal Flogical;arithmetical shiftsG and more
all fall into this category.
sign and 8ero e%tension. 3his is =hat mo's2bBl32l+3 and mo'(2bBl3l are for.
2emember that in 6.bit, Kero extension is done by default for "2bit o)erations %
there>s no need for a mo'(2bBl3+ instruction because that>s im)licit. -ut of course
sign extension to 6.bit, mo's2bBl3+, is re9uired no= and then,
3o loo$ u) the documentation for the remaining instructions named in the gra)hs,
sete;setne and stc, is left as an exercise to the reader, along =ith familiariKing
oneself =ith the Z"Y res). Z5Y of instructions that are classified as others above A
Cor the follo=ing exam)les, the given sourcecode =as com)iled using 0un Eor$sho)
15 cc and '&* gcc "..." using the commands/
cc )x<% -xarch=amd64 )c ....c
gcc )<$ -m64 )c ....c
3hin fixedwidth/ additional s=itch to create 6.bit code.
(n all assembly listings, color and font coding is used/
4reen sho=s function prologue and function epilogue.
+ed sho=s =hen the function acccesses its o=n arguments.
".Assembly <anguage on x86 )latforms 5"
2lue sho=s function calls Fand their argumentsG made by the given code.
thin italics designates branch targets =ithin the function.
3he codesam)les sho=n are of course only a small fraction of ?=hat is )ossible@. 3heir
)ur)ose is to illustrate both the general structure of com)iler6generated out)ut for
"2bit and 6.bit x86, and to demonstrate ho= different com)iler out)ut from t=o
different code generators Fthose of gcc and Eor$sho)G can become even in such sim)le
cases.
5. ".Assembly <anguage on x86 )latforms
'.9.".if01 ... else statements
0ourcecode sam)le/
Dinclude Cs;s/t;pes./7
Dinclude Cs;s/stat./7
Dinclude Cs;s/errno./7
Dinclude Cfcntl./7
Dinclude Cunistd./7
Dinclude Cstdio./7
int rfile0c/ar Efilename" 'oid Edestbuf" off6t offset" si(e6t nb;te1
V
int fdW
if 00fd [ open0filename" <6OK<>?S" !&&&11 C !1 V
perror0Yopen failedZ1W
return 0)#1W
X else if 0nb;tes 7 !1 V
if 0pread0fd" destbuf" nb;te" offset1 J[ nb;te1 V
perror0Ypread failedZ1W
return 0)$1W
X
X else V
printf0Yfooling me 5 >Q?? read at ull^nZ" offset1W
X
return 0!1W
X
3he exam)le =as com)iled adding _getconf ?@S6C@?HNS_ to com)iler s=itches. 3his
allo=s to demonstrate ho= 6.bit values are )assed as arguments in a "2bit )rogram.
Cor the "2bit code, =e find that the 6.bit value Foff6tG actually is )assed as t=o
se)arate "2bit values % in 4!x#!0ebp1 and 4!x#&0ebp1, in this case.
A)art from that, the "2bit assembler code sho=s com)iler differences.
2egarding o)timiKations, =e find/
3he 0un Eor$sho) com)iler tends to inline function e)ilogues multi)le time in
order to avoid branches. (nteresting to note that although it does this, the total
amount of code is still less than the gcc out)ut.
gcc on the other hand )uts arguments into nonvolatile registers in order to avoid
having to re6fetch them from the stac$.
2egarding ho= the stac$ is being used, =e see/
3he Eor$sho) com)iler aligns the stac$)ointer on entry but not on call, =here it
removes exactly the number of args after=ards using addl as it pus/l>ed before.
gcc doesn>t align the stac$)ointer on entry but =hen doing a function call, it al=ays
reserves a multi)le of 16 bytes F!x#!G for argument stac$s)ace % even if the called
function ta$es less than that.
".Assembly <anguage on x86 )latforms 55
('- !"bit binary> Sun 8or9shop cc ('- !"bit binary> 4?6 gcc !.7.!
rfile: pus/l ebp
rfile4!x#: mo'l esp"ebp
rfile4!x%: andl ,!xfffffff!"esp
rfile4!x6: pus/l ebx
rfile4!x.: pus/l ,!x#$&
rfile4!xc: pus/l ,!x!
rfile4!xe: pus/l !x80ebp1
rfile4!x##: call open6&
rfile4!x#6: addl ,!xc"esp
rfile4!x#*: testl eax"eax
rfile4!x#b: Tl Crfile+0x577
rfile4!x#d: mo'l !x#80ebp1"ebx
rfile4!x$!: testl ebx"ebx
rfile4!x$$: Tbe Crfile+0x3d7
rfile4!x$&: pus/l !x#&0ebp1
rfile4!x$.: pus/l !x#!0ebp1
rfile4!x$a: pus/l ebx
rfile4!x$b: pus/l !xc0ebp1
rfile4!x$e: pus/l eax
rfile4!x$f: call pread6&
rfile4!x%&: addl ,!x#&"esp
rfile4!x%.: cmpl ebx"eax
rfile4!x%*: Te Crfile+0x507
rfile4!x%b: Tmp Crfile+0x6e7
rfile+0x3d: pus/l !x#&0ebp1
rfile4!x&!: pus/l !x#!0ebp1
rfile4!x&%: pus/l ,printf6arg#
rfile4!x&8: call printf
rfile4!x&d: addl ,!xc"esp
rfile+0x50: xorl eax"eax
rfile4!x-$: popl ebx
rfile4!x-%: mo'l ebp"esp
rfile4!x--: popl ebp
rfile4!x-6: ret
rfile+0x57: pus/l ,perror6openfail
rfile4!x-c: call perror
rfile4!x6#: addl ,!x&"esp
rfile4!x6&: mo'l ,)!x#"eax
rfile4!x6*: popl ebx
rfile4!x6a: mo'l ebp"esp
rfile4!x6c: popl ebp
rfile4!x6d: ret
rfile+0x6e: pus/l ,perror6preadfail
rfile4!x.%: call perror
rfile4!x.8: addl ,!x&"esp
rfile4!x.b: mo'l ,)!x$"eax
rfile4!x8!: popl ebx
rfile4!x8#: mo'l ebp"esp
rfile4!x8%: popl ebp
rfile4!x8&: ret
rfile: pus/l ebp
rfile4!x#: mo'l esp"ebp
rfile4!x%: pus/l edi
rfile4!x&: pus/l esi
rfile4!x-: pus/l ebx
rfile4!x6: subl ,!x#!"esp
rfile4!x*: pus/l ,!x#$&
rfile4!xe: pus/l ,!x!
rfile4!x#!: pus/l !x80ebp1
rfile4!x#%: mo'l !x#!0ebp1"esi
rfile4!x#6: mo'l !x#&0ebp1"edi
rfile4!x#*: mo'l !x#80ebp1"ebx
rfile4!x#c: call open6&
rfile4!x$#: addl ,!x#!"esp
rfile4!x$&: testl eax"eax
rfile4!x$6: Ts Crfile+0x757
rfile4!x$8: testl ebx"ebx
rfile4!x$a: Te Crfile+0x4c7
rfile4!x$c: subl ,!xc"esp
rfile4!x$f: pus/l edi
rfile4!x%!: pus/l esi
rfile4!x%#: pus/l ebx
rfile4!x%$: pus/l !xc0ebp1
rfile4!x%-: pus/l eax
rfile4!x%6: call pread6&
rfile4!x%b: addl ,!x$!"esp
rfile4!x%e: cmpl ebx"eax
rfile4!x&!: Tne Crfile+0x5e7
rfile+0x42: xorl eax"eax
rfile+0x44: leal )!xc0ebp1"esp
rfile4!x&.: popl ebx
rfile4!x&8: popl esi
rfile4!x&*: popl edi
rfile4!x&a: lea'e
rfile4!x&b: ret
rfile+0x4c: pus/l eax
rfile4!x&d: pus/l edi
rfile4!x&e: pus/l esi
rfile4!x&f: pus/l ,printf6arg#
rfile4!x-&: call printf
rfile4!x-*: addl ,!x#!"esp
rfile4!x-c: Tmp Crfile+0x427
rfile+0x5e: subl ,!xc"esp
rfile4!x6#: pus/l ,perror6preadfail
rfile4!x66: call perror
rfile4!x6b: mo'l ,)!x$"eax
rfile4!x.!: addl ,!x#!"esp
rfile4!x.%: Tmp Crfile+0x447
rfile+0x75: subl ,!xc"esp
rfile4!x.8: pus/l ,perror6openfail
rfile4!x.d: call perror
rfile4!x8$: mo'l ,)!x#"eax
rfile4!x8.: addl ,!x#!"esp
rfile4!x8a: Tmp Crfile+0x447
56 ".Assembly <anguage on x86 )latforms
('- -7bit binary> Sun 8or9shop cc ('- -7bit binary> 4?6 gcc !.7.!
rfile: pus/+ rbp
rfile4!x#: mo'+ rsp"rbp
rfile4!x&: sub+ ,!x8"rsp
rfile4!x8: pus/+ r#$
rfile4!xa: pus/+ r#%
rfile4!xc: pus/+ r#&
rfile4!xe: mo'+ rsi"r#&
rfile4!x##: mo'+ rdx"r#$
rfile4!x#&: mo'+ rcx"r#%
rfile4!x#.: xorl esi"esi
rfile4!x#*: mo'l ,!x#$&"edx
rfile4!x#e: xorl eax"eax
rfile4!x$!: call open
rfile4!x$-: testl eax"eax
rfile4!x$.: Tl Crfile+0x657
rfile4!x$*: test+ r#%"r#%
rfile4!x$c: Te Crfile+0x477
rfile4!x$e: mo'l eax"edi
rfile4!x%!: mo'+ r#&"rsi
rfile4!x%%: mo'+ r#%"rdx
rfile4!x%6: mo'+ r#$"rcx
rfile4!x%*: xorl eax"eax
rfile4!x%b: call pread
rfile4!x&!: cmp+ r#%"rax
rfile4!x&%: Te Crfile+0x587
rfile4!x&-: Tmp Crfile+0x837
rfile+0x47: lea+ printfarg0rip1"rdi
rfile4!x&e: mo'+ r#$"rsi
rfile4!x-#: xorl eax"eax
rfile4!x-%: call printf
rfile+0x58: xorl eax"eax
rfile4!x-a: pop+ r#&
rfile4!x-c: pop+ r#%
rfile4!x-e: pop+ r#$
rfile4!x6!: mo'+ rbp"rsp
rfile4!x6%: pop+ rbp
rfile4!x6&: ret
rfile+0x65: lea+ err6open0rip1"rdi
rfile4!x6c: xorl eax"eax
rfile4!x6e: call perror
rfile4!x.%: mo'l ,)!x#"eax
rfile4!x.8: pop+ r#&
rfile4!x.a: pop+ r#%
rfile4!x.c: pop+ r#$
rfile4!x.e: mo'+ rbp"rsp
rfile4!x8#: pop+ rbp
rfile4!x8$: ret
rfile4!x8%: lea+ err6pread0rip1"rdi
rfile4!x8a: xorl eax"eax
rfile4!x8c: call perror
rfile4!x*#: mo'l ,)!x$"eax
rfile4!x*6: pop+ r#&
rfile4!x*8: pop+ r#%
rfile4!x*a: pop+ r#$
rfile4!x*c: mo'+ rbp"rsp
rfile4!x*f: pop+ rbp
rfile4!xa!: ret
rfile: pus/+ rbp
rfile4!x#: xorl eax"eax
rfile4!x%: mo'+ rsp"rbp
rfile4!x6: mo'+ rbx")!x#80rbp1
rfile4!xa: mo'+ r#$")!x#!0rbp1
rfile4!xe: mo'+ rdx"r#$
rfile4!x##: mo'+ r#%")!x80rbp1
rfile4!x#-: mo'l ,!x#$&"edx
rfile4!x#a: sub+ ,!x$!"rsp
rfile4!x#e: mo'+ rsi"r#%
rfile4!x$#: xorl esi"esi
rfile4!x$%: mo'+ rcx"rbx
rfile4!x$6: call open
rfile4!x$b: testl eax"eax
rfile4!x$d: Ts Crfile+0x827
rfile4!x$f: test+ rbx"rbx
rfile4!x%$: Te Crfile+0x607
rfile4!x%&: mo'+ r#$"rcx
rfile4!x%.: mo'+ rbx"rdx
rfile4!x%a: mo'+ r#%"rsi
rfile4!x%d: mo'l eax"edi
rfile4!x%f: call pread
rfile4!x&&: cmp+ rbx"rax
rfile4!x&.: Tne Crfile+0x717
rfile+0x49: xorl eax"eax
rfile+0x4b: mo'+ )!x#80rbp1"rbx
rfile4!x&f: mo'+ )!x#!0rbp1"r#$
rfile4!x-%: mo'+ )!x80rbp1"r#%
rfile4!x-.: lea'e
rfile4!x-8: ret
rfile4!x-*: nop
rfile4!x-d: nop
rfile+0x60: mo'+ r#$"rsi
rfile4!x6%: mo'l ,printf6arg"edi
rfile4!x68: xorl eax"eax
rfile4!x6a: call printf
rfile4!x6f: Tmp Crfile+0x497
rfile+0x71: mo'l ,err6pread"edi
rfile4!x.6: call perror
rfile4!x.b: mo'l ,)!x$"eax
rfile4!x8!: Tmp Crfile+0x4b7
rfile+0x82: mo'l ,err6open"edi
rfile4!x8.: call perror
rfile4!x8c: mo'l ,)!x#"eax
rfile4!x*#: Tmp Crfile+0x4b7
".Assembly <anguage on x86 )latforms 57
58 ".Assembly <anguage on x86 )latforms
3he 6.bit code sho=s several interesting )eculiarities beyond the A-( differences Fargs
in registers, and Keroing rax before calling a functionG that need ex)lanation.
-oth Eor$sho) cc and gcc for exam)le seemingly fail to initialiKe the first argument
for open01 6 neither =rites to rdi. 3his is of course correct % it>ll )ass6through the
in)ut value. 3he filename is not needed anymore after this, so it isn>t saved any=here.
3hat>s not true for the remaining arguments to rfile01. 3hey>re still needed, so both
cc and gcc decide to $ee) these in nonvolatile registers % but only gcc recogniKes that
using rbx is more efficient than using r#$..r#-.
As =ith "2bit code, Eor$sho) cc inlines the e)ilogue several times =hile gcc $ee)s a
single co)y. Also, as mentioned, gcc uses lea'e =hile Eor$sho) cc uses the e9uivalent
t=o6instruction se9uence.
3he 0un Eor$sho) com)iler sho=s that position!independent code on A#76. is very
efficiently doable via rip6relative addressing. 0un Eor$sho) cc defaults to that for
loading the addresses of the strings )assed as arguments to printf01 and perror01.
gcc>s )rologue code here demonstrates the use of the so6called stack red8one. (n gcc>s
terms, the redKone are the 128 bytes of unallocated stac$s)ace immediately belo= the
current value of the stac$)ointer. 3his can be accessed using byte offsets relative to
the stac$;frame)ointer, =hich is =hat gcc does here instead of using pus/+
instructions.
(.e. gcc accesses the stac$ first, and allocates it later.
(t is debatable =hether this is an o)timiKationN in any case, this behaviour is highly
incompatible =ith $ernel code both in <inux and 0olaris % the $ernel is )reem)tive
and running =ith interru)ts enabled, and those events may use the current thread>s
stac$ belo= =hat the stac$)ointer is at the time the interru)t occurs. (n both <inux
and 0olaris $ernels, gcc>s redKone usage must be disabled or data corru)tion F=ith a
crash li$ely soon after=ardsG =ill result if an interru)t occurs before the subl ..."
rsp has been done.
gcc )rovides a com)ile flag, )mno)red)(one, that must be used =hen com)iling $ernel
code =ith gcc, both under 0olaris and <inux. (t ma$es sure gcc allocates stac$s)ace
before attem)ting to use it.
Cor a))lication code, the use of the stac$ redKone is not a )roblem in either 0olaris or
<inux % the A#76. *&(+ A-( guarantees its availability to applications.
".Assembly <anguage on x86 )latforms 5
'.9.'.for01 loop example
0ourcecode/
extern int get6a6num0'oid1W
long loopit0int times1
V
long tmp [ #$%W
int iW
for 0i [ #!W i C timesW i441 V
tmp 4[ get6a6num01W
tmp )[ get6a6num01W
X
return 0tmp1W
X
7isassembler out)ut/
('- !"bit binary> Sun 8or9shop cc ('- !"bit binary> 4?6 gcc !.7.!
loopit: pus/l ebp
loopit4!x#: mo'l esp"ebp
loopit4!x%: andl ,!xfffffff!"esp
loopit4!x6: pus/l ebx
loopit4!x.: pus/l esi
loopit4!x8: pus/l edi
loopit4!x*: mo'l !x80ebp1"edi
loopit4!xc: mo'l ,!x.b"esi
loopit4!x##: cmpl ,!xa"edi
loopit4!x#&: Tle Cloopit+0x2e7
loopit4!x#6: mo'l ,!xa"ebx
loopit+0x1b: call get6a6num
loopit4!x$!: addl eax"esi
loopit4!x$$: call get6a6num
loopit4!x$.: subl eax"esi
loopit4!x$*: incl ebx
loopit4!x$a: cmpl edi"ebx
loopit4!x$c: Tl Cloopit+0x1b7
loopit+0x2e: mo'l esi"eax
loopit4!x%!: popl edi
loopit4!x%#: popl esi
loopit4!x%$: popl ebx
loopit4!x%%: mo'l ebp"esp
loopit4!x%-: popl ebp
loopit4!x%6: ret
loopit: pus/l ebp
loopit4!x#: mo'l esp"ebp
loopit4!x%: mo'l !x80ebp1"eax
loopit4!x6: pus/l esi
loopit4!x.: cmpl ,!xa"eax
loopit4!xa: pus/l ebx
loopit4!xb: mo'l ,!x.b"esi
loopit4!x#!: Tle Cloopit+0x297
loopit4!x#$: leal )!xa0eax1"ebx
loopit4!x#-: leal !x!0esi1"esi
loopit+0x18: call get6a6num
loopit4!x#d: addl eax"esi
loopit4!x#f: call get6a6num
loopit4!x$&: subl eax"esi
loopit4!x$6: decl ebx
loopit4!x$.: Tne Cloopit+0x187
loopit+0x29: popl ebx
loopit4!x$a: mo'l esi"eax
loopit4!x$c: popl esi
loopit4!x$d: lea'e
loopit4!x$e: ret
!om)iler differences are obvious here/
3he Eor$sho) com)iler uses three nonvolatile registers, edi, esi and ebx, for
the three variables times, tmp and i" and counts the loo) for=ard, starting at 15.
3he '&* ! com)iler eliminates i as a variable and instead counts 0times)#!1
do=n=ards to Kero. (t therefore only uses esi for tmp and ebx for the inverted
counter. (t also interleaves the pus/l o)erations in the )rologue =ith instructions
that don>t access memory.
65 ".Assembly <anguage on x86 )latforms
('- -7bit binary> Sun 8or9shop cc ('- -7bit binary> 4?6 gcc !.7.!
loopit: pus/+ rbp
loopit4!x#: mo'+ rsp"rbp
loopit4!x&: pus/+ rbx
loopit4!x-: pus/+ r#$
loopit4!x.: pus/+ r#%
loopit4!x*: pus/+ r#&
loopit4!xb: mo'l edi"r#%d
loopit4!xe: mo'+ ,!x.b"r#&
loopit4!x#-: mo'l ,!xa"ebx
loopit4!x#a: cmpl ,!xa"r#%d
loopit4!x#e: Tle Cloopit+0x447
loopit+0x20: xorl eax"eax
loopit4!x$$: call get6a6num
loopit4!x$.: mo'sl+ eax"r#$
loopit4!x$a: add+ r#&"r#$
loopit4!x$d: xorl eax"eax
loopit4!x$f: call get6a6num
loopit4!x%&: mo'sl+ eax"r8
loopit4!x%.: mo'+ r#$"r#&
loopit4!x%a: sub+ r8"r#&
loopit4!x%d: incl ebx
loopit4!x%f: cmpl r#%d"ebx
loopit4!x&$: Tl Cloopit+0x207
loopit+0x44: mo'+ r#&"rax
loopit4!x&.: pop+ r#&
loopit4!x&*: pop+ r#%
loopit4!x&b: pop+ r#$
loopit4!x&d: pop+ rbx
loopit4!x&e: mo'+ rbp"rsp
loopit4!x-#: pop+ rbp
loopit4!x-$: ret
loopit: pus/+ rbp
loopit4!x#: cmpl ,!xa"edi
loopit4!x&: mo'+ rsp"rbp
loopit4!x.: pus/+ r#$
loopit4!x*: mo'l ,!x.b"r#$d
loopit4!xf: pus/+ rbx
loopit4!x#!: Tle Cloopit+0x2d7
loopit4!x#$: leal )!xa0rdi1"ebx
loopit+0x15: call get6a6num
loopit4!x#a: clt+
loopit4!x#c: add+ rax"r#$
loopit4!x#f: call get6a6num
loopit4!x$&: clt+
loopit4!x$6: sub+ rax"r#$
loopit4!x$*: decl ebx
loopit4!x$b: Tne Cloopit+0x157
loopit+0x2d: pop+ rbx
loopit4!x$e: mo'+ r#$"rax
loopit4!x%#: pop+ r#$
loopit4!x%%: lea'e
loopit4!x%&: ret
3he 6.bit code sho=s the A-( differencesN both com)ilers do/
access the FonlyG argument via edi Fnot rdi % the argument is ty)e intG
clear rax Fnot eax % remember "2bit o)erations Kero6extendG before calling
get6a6num01 before ma$ing a function call. 3his is mandated by the 6.bit A-(.
Eor$sho) cc uses xorl for the )ur)ose
gcc chooses clt+. Fclear6to69uad, Keroes both eax and edxG.
3he gcc 6.bit code loo$s almost identical to the "2bit code other=ise. -ut the 0un
Eor$sho) com)iler has chosen to use four registers Fnot three as in "2bitG, using t=o
registers for the intermediate values of tmp.
".Assembly <anguage on x86 )latforms 61
'.9.*.sBitc/01 statements
0ourcecode/
Dinclude Cstdio./7
extern 'oid func6a0int1W
extern 'oid func6b0int1W
extern 'oid func6c0'oid1W
extern 'oid func6d0int1W
extern 'oid func6e0long1W
extern 'oid func6default0int1W
'oid disp0long code1
V
sBitc/ 0code1 V
case $8!:
func6a0#1W
breakW
case 88!:
func6b0$1W
breakW
case *$:
func6c01W
breakW
case #!#:
func6d0%1W
breakW
case $%.:
func6e0code1W
breakW
default:
func6default0&1W
breakW
X
printf0Idispatc/ done for ld^nI" code1W
X
3his is the most6com)licated exam)le in this section.
3here are multi)le =ays ho= com)ilers can create assembly code for such source. 0un
Eor$sho) cc and gcc actually aren>t that dissimilar here, both, in "2bit as in 6.bit,
create se9uences of cmp;Te instructions follo=ed by a direct Tmp to the reach the end
of the sBitc/ VX statement.
7e)ending on the exact structure of the sBitc/ VX, and the values case: chec$ for,
many o)timiKations are )ossible of course, and one cannot ex)ect a generic, real6=orld
sourcecode to result in assembly code as easy to read as that given on the follo=ing
)ages. 3his is one exam)le of ho= assembly code for sBitc/ VX can loo$ li$e % but
reality =ill often be more com)lex.
62 ".Assembly <anguage on x86 )latforms
('- !"bit binary> Sun 8or9shop cc ('- !"bit binary> 4?6 gcc !.7.!
disp: pus/l ebp
disp4!x#: mo'l esp"ebp
disp4!x%: andl ,!xfffffff!"esp
disp4!x6: pus/l ebx
disp4!x.: mo'l !x80ebp1"ebx
disp4!xa: cmpl ,!x-c"ebx
disp4!xd: Te Cdisp+0x677
disp4!xf: cmpl ,!x6-"ebx
disp4!x#$: Te Cdisp+0x5b7
disp4!x#&: cmpl ,!xed"ebx
disp4!x#a: Te Cdisp+0x507
disp4!x#c: cmpl ,!x##8"ebx
disp4!x$$: Te Cdisp+0x447
disp4!x$&: cmpl ,!x%.!"ebx
disp4!x$a: Te Cdisp+0x387
disp4!x$c: pus/l ,!x&
disp4!x$e: call func6default
disp4!x%%: addl ,!x&"esp
disp4!x%6: Tmp Cdisp+0x6c7
disp+0x38: pus/l ,!x$
disp4!x%a: call func6b
disp4!x%f: addl ,!x&"esp
disp4!x&$: Tmp Cdisp+0x6c7
disp+0x44: pus/l ,!x#
disp4!x&6: call func6a
disp4!x&b: addl ,!x&"esp
disp4!x&e: Tmp Cdisp+0x6c7
disp+0x50: pus/l ebx
disp4!x-#: call func6e
disp4!x-6: addl ,!x&"esp
disp4!x-*: Tmp Cdisp+0x6c7
disp+0x5b: pus/l ,!x%
disp4!x-d: call func6d
disp4!x6$: addl ,!x&"esp
disp4!x6-: Tmp Cdisp+0x6c7
disp+0x67: call func6c
disp+0x6c: pus/l ebx
disp4!x6d: pus/l ,printf6arg#
disp4!x.$: call printf
disp4!x..: addl ,!x8"esp
disp4!x.a: popl ebx
disp4!x.b: mo'l ebp"esp
disp4!x.d: popl ebp
disp4!x.e: ret
disp: pus/l ebp
disp4!x#: mo'l esp"ebp
disp4!x%: pus/l ebx
disp4!x&: pus/l eax
disp4!x-: mo'l !x80ebp1"ebx
disp4!x8: cmpl ,!xed"ebx
disp4!xe: Te Cdisp+0x607
disp4!x#!: Tle Cdisp+0x487
disp4!x#$: cmpl ,!x##8"ebx
disp4!x#8: Te Cdisp+0x6f7
disp4!x#a: cmpl ,!x%.!"ebx
disp4!x$!: Te Cdisp+0x827
disp+0x22: subl ,!xc"esp
disp4!x$-: pus/l ,!x&
disp4!x$.: call func6default
disp+0x2c: addl ,!x#!"esp
disp+0x2f: subl ,!x8"esp
disp4!x%$: pus/l ebx
disp4!x%%: pus/l ,printf6arg#
disp4!x%8: call printf
disp4!x%d: addl ,!x#!"esp
disp4!x&!: mo'l )!x&0ebp1"ebx
disp4!x&%: lea'e
disp4!x&&: ret
disp4!x&-: leal !x!0esi1"esi
disp+0x48: cmpl ,!x-c"ebx
disp4!x&b: Te Cdisp+0x7b7
disp4!x&d: cmpl ,!x6-"ebx
disp4!x-!: Tne Cdisp+0x227
disp4!x-$: subl ,!xc"esp
disp4!x--: pus/l ,!x%
disp4!x-.: call func6d
disp4!x-c: Tmp Cdisp+0x2c7
disp4!x-e: mo'l esi"esi
disp+0x60: subl ,!xc"esp
disp4!x6%: pus/l ,!xed
disp4!x68: call func6e
disp4!x6d: Tmp Cdisp+0x2c7
disp+0x6f: subl ,!xc"esp
disp4!x.$: pus/l ,!x#
disp4!x.&: call func6a
disp4!x.*: Tmp Cdisp+0x2c7
disp+0x7b: call func6c
disp4!x8!: Tmp Cdisp+0x2f7
disp+0x82: subl ,!xc"esp
disp4!x8-: pus/l ,!x$
disp4!x8.: call func6b
disp4!x8c: Tmp Cdisp+0x2c7
&ote that this code sho=s a difference in ho= Eor$sho) cc and gcc )ass arguments.
Ehile Eor$sho) cc uses pus/l;call;addl to )ut arguments onto the stac$ and remove
exactly this amount from the stac$ again after the function call, '&* gcc allocates 16
bytes of stac$s)ace for args even if the called function uses less than that.
".Assembly <anguage on x86 )latforms 6"
('- -7bit binary> Sun 8or9shop cc ('- -7bit binary> 4?6 gcc !.7.!
disp: pus/+ rbp
disp4!x#: mo'+ rsp"rbp
disp4!x&: sub+ ,!x8"rsp
disp4!x8: pus/+ r#$
disp4!xa: mo'+ rdi"r#$
disp4!xd: cmp+ ,!x-c"r#$
disp4!x##: Te Cdisp+0x787
disp4!x#%: cmp+ ,!x6-"r#$
disp4!x#.: Te Cdisp+0x6a7
disp4!x#*: cmp+ ,!xed"r#$
disp4!x$!: Te Cdisp+0x5e7
disp4!x$$: cmp+ ,!x##8"r#$
disp4!x$*: Te Cdisp+0x507
disp4!x$b: cmp+ ,!x%.!"r#$
disp4!x%$: Te Cdisp+0x427
disp4!x%&: mo'l ,!x&"edi
disp4!x%*: xorl eax"eax
disp4!x%b: call func6default
disp4!x&!: Tmp Cdisp+0x7f7
disp+0x42: mo'l ,!x$"edi
disp4!x&.: xorl eax"eax
disp4!x&*: call func6b
disp4!x&e: Tmp Cdisp+0x7f7
disp+0x50: mo'l ,!x#"edi
disp4!x--: xorl eax"eax
disp4!x-.: call func6a
disp4!x-c: Tmp Cdisp+0x7f7
disp+0x5e: mo'+ r#$"rdi
disp4!x6#: xorl eax"eax
disp4!x6%: call func6e
disp4!x68: Tmp Cdisp+0x7f7
disp+0x6a: mo'l ,!x%"edi
disp4!x6f: xorl eax"eax
disp4!x.#: call func6d
disp4!x.6: Tmp Cdisp+0x7f7
disp+0x78: xorl eax"eax
disp4!x.a: call func6c
disp+0x7f: lea+ printf6arg#0rip1"rdi
disp4!x86: mo'+ r#$"rsi
disp4!x8*: xorl eax"eax
disp4!x8b: call printf
disp4!x*!: pop+ r#$
disp4!x*$: mo'+ rbp"rsp
disp4!x*-: pop+ rbp
disp4!x*6: ret
disp: pus/+ rbp
disp4!x#: mo'+ rsp"rbp
disp4!x&: pus/+ rbx
disp4!x-: mo'+ rdi"rbx
disp4!x8: sub+ ,!x8"rsp
disp4!xc: cmp+ ,!xed"rdi
disp4!x#%: Te Cdisp+0x687
disp4!x#-: Tle Cdisp+0x507
disp4!x#.: cmp+ ,!x##8"rdi
disp4!x#e: Te Cdisp+0x877
disp4!x$!: cmp+ ,!x%.!"rdi
disp4!x$.: Te Cdisp+0xa27
disp+0x29: mo'l ,!x&"edi
disp4!x$e: nop
disp4!x%!: call func6default
disp+0x35: add+ ,!x8"rsp
disp4!x%*: mo'+ rbx"rsi
disp4!x%c: mo'l ,printf6arg#"edi
disp4!x&#: pop+ rbx
disp4!x&$: lea'e
disp4!x&%: xorl eax"eax
disp4!x&-: Tmp printf
disp4!x&a: nop
disp4!x&d: nop
disp+0x50: cmp+ ,!x-c"rdi
disp4!x-&: Te Cdisp+0x937
disp4!x-6: cmp+ ,!x6-"rdi
disp4!x-a: Tne Cdisp+0x297
disp4!x-c: mo'l ,!x%"edi
disp4!x6#: call func6d
disp4!x66: Tmp Cdisp+0x357
disp+0x68: mo'l ,!xed"edi
disp4!x6d: call func6e
disp4!x.$: add+ ,!x8"rsp
disp4!x.6: mo'+ rbx"rsi
disp4!x.*: mo'l ,printf6arg#"edi
disp4!x.e: pop+ rbx
disp4!x.f: lea'e
disp4!x8!: xorl eax"eax
disp4!x8$: Tmp printf
disp+0x87: mo'l ,!x#"edi
disp4!x8c: call func6a
disp4!x*#: Tmp Cdisp+0x357
disp+0x93: call func6c
disp4!x*8: nop
disp4!x*c: nop
disp4!xa!: Tmp Cdisp+0x357
disp+0xa2: mo'l ,!x$"edi
disp4!xa.: call func6b
disp4!xac: nop
disp4!xb!: Tmp Cdisp+0x357
-oth com)ilers generated similar code com)ared to their "2bit out)ut. &ote that
Eor$sho) cc by used rip6relative Fposition independentG for loading the address of
printf01>s format string, =hile gcc uses tail!call optimi8ation and Tmp>s to printf01.
6. ".Assembly <anguage on x86 )latforms
'.8.#essing data str!t!res
3he various addressing modes su)))orted by x86 are fre9uently used in com)iled
code. 3hey match very =ell =ith the =ay the ! )rogramming language im)lements
structures and arrays. 3he follo=ing section =ill demonstrate/
ho= global and local variables differ, and =here arguments fit in
=hat conse9uences to the assembly out)ut it has if the com)iler is instructed to
create )osition6inde)endent code.
8ariations of the follo=ing sourcecode =ill be used/
Dinclude Cstring./7
t;pedef struct st6s V
c/ar s6cW
long s6lW
s/ort s6sW
int s6iW
c/ar s6name2$%3W
struct st6s Es6nxtW
X sts6tW
/E
E Aariant H:
E structure to be initiali(ed is passed as an argument
E/
'oid initstruct0
sts6t Einitme"
c/ar i6c"
long i6l"
s/ort i6s"
int i6i"
c/ar Ei6name
1
V
initme)7s6c [ i6c 4 #W
initme)7s6l [ i6l 4 $W
initme)7s6s [ i6s 4 %W
initme)7s6i [ i6i 4 &W
strcp;0initme)7s6name" i6name1W
initme)7s6name2$!3 [ ]H]
initme)7s6nxt [ >Q??W
X
'.8.1.#rg!ments1 types1 str!t!re aess
'"=6*bit #6$ omparison
3he above6sho=n sourcecode is designed to sho= A-( differences. 0ince arguments are
used;ty)ed in a =ay sim)le enough to identify, any change in "2;6.bit =rt. to/
argument access
data structure member alignment
siKes of data ty)es
function calling
become immediately obvious.
".Assembly <anguage on x86 )latforms 65
A different color coding than before is used/
red are Fin)utG arguments
green are local variables Fon the stac$ % local variables in registers aren>t mar$edG
blue are global variables
thin italics red are out)ut arguments, i.e. values )assed to a called function
!"bit binary> Sun 8or9shop cc -7bit binary> Sun 8or9shop cc
initstruct: pus/l ebp
initstruct4!x#: mo'l esp"ebp
initstruct4!x%: andl ,!xfffffff!"esp
initstruct4!x6: pus/l ebx
initstruct4!x.: mo'sbl !xc0ebp1"eax
initstruct4!xb: incl eax
initstruct4!xc: mo'l !x80ebp1"ebx
initstruct4!xf: mo'b al"0ebx1
initstruct4!x##: mo'l !x#!0ebp1"eax
initstruct4!x#&: addl ,!x$"eax
initstruct4!x#.: mo'l eax"!x&0ebx1
initstruct4!x#a: mo'sBl !x#&0ebp1"eax
initstruct4!x#e: addl ,!x%"eax
initstruct4!x$#: mo'B ax"!x80ebx1
initstruct4!x$-: mo'l !x#80ebp1"eax
initstruct4!x$8: addl ,!x&"eax
initstruct4!x$b: mo'l eax"!xc0ebx1
initstruct4!x$e: pshl !x#c0ebp1
initstruct4!x%#: leal !x#!0ebx1"eax
initstruct4!x%&: pshl !eax
initstruct4!x%-: call Cstrcp;7
initstruct4!x%a: addl ,!x8"esp
initstruct4!x%d: mo'b ,!x&#"!x$&0ebx1
initstruct4!x&#: mo'l ,!x!"!x$80ebx1
initstruct4!x&8: popl ebx
initstruct4!x&*: mo'l ebp"esp
initstruct4!x&b: popl ebp
initstruct4!x&c: ret
initstruct: pus/+ rbp
initstruct4!x#: mo'+ rsp"rbp
initstruct4!x&: sub+ ,!x8"rsp
initstruct4!x8: pus/+ r#$
initstruct4!xa: mo'+ rdi"r#$
initstruct4!xd: mo'+ rdx"r#!
initstruct4!x#!: mo'sbl sil"eax
initstruct4!x#&: incl eax
initstruct4!x#6: mo'b al"0r#$1
initstruct4!x#a: add+ ,!x$"r#!
initstruct4!x#e: mo'+ r#!"!x80r#$1
initstruct4!x$%: mo'sBl cx"eax
initstruct4!x$6: addl ,!x%"eax
initstruct4!x$*: mo'B ax"!x#!0r#$1
initstruct4!x$f: addl ,!x&"r8d
initstruct4!x%%: mo'l r8d"!x#&0r#$1
initstruct4!x%8: mo'+ r#$"rdi
initstruct4!x%b: add+ ,!x#8"!rdi
initstruct4!x%f: mo'+ r*"!rsi
initstruct4!x&$: xorl eax"eax
initstruct4!x&&: call Cstrcp;7
initstruct4!x&*: mo'b ,!x&#"!x$c0r#$1
initstruct4!x&f: mo'+ ,!x!"!x%!0r#$1
initstruct4!x-8: pop+ r#$
initstruct4!x-a: mo'+ rbp"rsp
initstruct4!x-d: pop+ rbp
initstruct4!x-e: ret
7ifferences/
1. 0iKe of basic data ty)es has changed. arg" Fof ty)e longG is "2bit in "2bit mode but
6.bit in 6.bit mode. 0iKes of )ointers also changed, of course. (<1"2 vs. <16..
2. Alignment of basic ty)es changed. long and c/arE Fs6l and s6nameG are .6-yte
aligned in "2bit but 86-yte aligned in 6.bit mode. Access to sts6t loo$s li$e/
struct st6s V
!"bit access -7bit access
c/ar s6cW mo'b al" 0ebx1 mo'b al" 0r#$1
long s6lW mo'l eax" !x&0ebx1 mo'+ r#!" !x80r#$1
s/ort s6sW mo'B ax" !x80ebx1 mo'B ax" !x#!0r#$1
int s6iW mo'l eax" !xc0ebx1 mo'l r8d"!x#&0r#$1
c/ar s6name2$%3W leal !x#!0ebx1"eax add+ ,!x#8"!rdi
sts6t Es6nxtW mo'l ,!x!"!x$80ebx1 mo'+ ,!x!"!x%!0r#$1
X
". Argument )assing % in)ut arguments all on the stac$ in "2bit mode, first six in
registers in 6.bit mode/
argument !"bit access -7bit access
[5/ sts6t Einitme
mo'l !x80ebp1"ebx mo'+ rdi"r#$
66 ".Assembly <anguage on x86 )latforms
argument !"bit access -7bit access
[1/ c/ar i6c
mo'sbl !xc0ebp1"eax mo'sbl sil"eax
[2/ long i6l mo'l !x#!0ebp1"eax mo'+ rdx"r#!
["/ s/ort i6s
mo'sBl !x#&0ebp1"eax mo'sBl cx"eax
[./ int i6i mo'l !x#80ebp1"eax mo'l r8d"!x#&0r#$1
[5/ c/ar Ei6name
pshl !x#c0ebp1 mo'+ r*"!rsi
.. Argument )assing % out)ut arguments Fto strcp;01G all on the stac$ in "2bit mode,
in rsi;rdi in 6.bit mode.
Additionally, 6.bit mode clears eax before ma$ing a function call.
(n short, a)art from the changes in argument )assing =e note that data ty)e siKes
have changed. "2bit x86 is (<1"2 Fint, long, and pointers all being "2bitG, =hile the
6.bit mode is <16. Flong and pointers are 6.bitG. 3he siKe change goes in line =ith a
change in alignment of data structures % long and pointer ty)es are aligned at a
multi)le of four bytes in "2bit x86, =hile in 6.bit mode they>re both at a multi)le of
eight bytes.
'.8.".#rg!ment aess &s. loal &ariables
3he follo=ing code modifies the )reviously6sho=n sam)le )rogram so that
init6struct01 initialiKes a local instance of stsSt before co)ying the contents thereof
into the )assed6in address/
'oid initstruct0
sts6t Einitme"
c/ar i6c"
long i6l"
s/ort i6s"
int i6i"
c/ar Ei6name
1
V
sts6t localcop;W
localcop;.s6c [ i6c 4 #W
localcop;.s6l [ i6l 4 $W
localcop;.s6s [ i6s 4 %W
localcop;.s6i [ i6i 4 &W
strcp;0localcop;.s6name" i6name1W
localcop;.s6name2$!3 [ ]H]W
localcop;.s6nxt [ >Q??W
memcp;0initme" \localcop;" si(eof0sts6t11W
X
3his allo=s us to see ho= access to local variables and arguments differs in com)iled
code. <et>s com)are the )reviously6sho=n code that initialiKes the members of Einitme
directly =ith the ne= version that initialiKes a local instance and co)ies that to
Einitme at the end.
".Assembly <anguage on x86 )latforms 67
Cirst, "2bit code/
initiali@ing via arg> cc> !"bit using local variable> cc> !"bit
initstruct: pus/l ebp
initstruct4!x#: mo'l esp"ebp
initstruct4!x%: andl ,!xfffffff!"esp
initstruct4!x6: pus/l ebx
initstruct4!x.: mo'sbl !xc0ebp1"eax
initstruct4!xb: incl eax
initstruct4!xc: mo'l !x80ebp1"ebx
initstruct4!xf: mo'b al"0ebx1
initstruct4!x##: mo'l !x#!0ebp1"eax
initstruct4!x#&: addl ,!x$"eax
initstruct4!x#.: mo'l eax"!x&0ebx1
initstruct4!x#a: mo'sBl !x#&0ebp1"eax
initstruct4!x#e: addl ,!x%"eax
initstruct4!x$#: mo'B ax"!x80ebx1
initstruct4!x$-: mo'l !x#80ebp1"eax
initstruct4!x$8: addl ,!x&"eax
initstruct4!x$b: mo'l eax"!xc0ebx1
initstruct4!x$e: pshl !x#c0ebp1
initstruct4!x%#: leal !x#!0ebx1"!eax
initstruct4!x%&: pshl !eax
initstruct4!x%-: call Cstrcp;7
initstruct4!x%a: addl ,!x8"esp
initstruct4!x%d: mo'b ,!x&#"!x$&0ebx1
initstruct4!x&#: mo'l ,!x!"!x$80ebx1
initstruct4!x&8: popl ebx
initstruct4!x&*: mo'l ebp"esp
initstruct4!x&b: popl ebp
initstruct4!x&c: ret
initstruct: pus/l ebp
initstruct4!x#: mo'l esp"ebp
initstruct4!x%: subl ,!x%!"esp
initstruct4!x6: andl ,!xfffffff!"esp
initstruct4!x*: mo'sbl !xc0ebp1"eax
initstruct4!xd: incl eax
initstruct4!xe: mo'b al"!x&0esp1
initstruct4!x#$: mo'l !x#!0ebp1"eax
initstruct4!x#-: addl ,!x$"eax
initstruct4!x#8: mo'l eax"!x80esp1
initstruct4!x#c: mo'sBl !x#&0ebp1"eax
initstruct4!x$!: addl ,!x%"eax
initstruct4!x$%: mo'B ax"!xc0esp1
initstruct4!x$8: mo'l !x#80ebp1"eax
initstruct4!x$b: addl ,!x&"eax
initstruct4!x$e: mo'l eax"!x#!0esp1
initstruct4!x%$: leal !x#&0esp1"!eax
initstruct4!x%6: pshl !x#c0ebp1
initstruct4!x%*: pshl !eax
initstruct4!x%a: call Cstrcp;7
initstruct4!x%f: addl ,!x8"esp
initstruct4!x&$: mo'b ,!x&#"!x$80esp1
initstruct4!x&.: mo'l ,!x!"!x$c0esp1
initstruct4!x&f: pus/l ,!x$c
initstruct4!x-#: leal !x80esp1"!eax
initstruct4!x--: pshl !eax
initstruct4!x-6: mo'l !x80ebp1"!eax
initstruct4!x-*: pshl !eax
initstruct4!x-a: call Cmemcp;7
initstruct4!x-f: mo'l ebp"esp
initstruct4!x6#: popl ebp
initstruct4!x6$: ret
3his sho=s that the =or$sho) com)iler, in this case, has chosen to access arguments
via 4...0ebp1, i.e. relative to the beginning of the function>s stac$frame, =hile the
second version sho=s it accesses local #ariables via 4...0esp1, relative to the end of
the stac$frame.
Ehile arguments in "2bit mode, if there is a frame)ointer, =ill al=ays be accessed via
4...0ebp1, it>s common to see both 4...0esp1 and )...0ebp1 for local variables.
3he follo=ing com)arison bet=een "2bit cc;gcc out)ut sho=s this clearly % the 0un
Eor$sho) com)iler for the given exam)le code has generated assembly =hich
accesses local variables relative to the stac$)ointer, 4...0esp1, =hile gcc for the
same sources creates assembly code that uses negative offsets relative to the
frame)ointer, )...0ebp1 for the same.
68 ".Assembly <anguage on x86 )latforms
&o matter =hat % in "2bit code that uses frame)ointers, the follo=ing is al=ays true/
5rguments/ before the start of the stac$frame, and accessed via 480ebp1 on=ards.
?ocal #ariables/ -elo= ebp, above esp. Access via )...0ebp1 or 4...0esp1.
local variables> !"bit> 8or9shop cc local variables> !"bit> 4?6 gcc
initstruct: pus/l ebp
initstruct4!x#: mo'l esp"ebp
initstruct4!x%: subl ,!x%!"esp
initstruct4!x6: andl ,!xfffffff!"esp
initstruct4!x*: mo'sbl !xc0ebp1"eax
initstruct4!xd: incl eax
initstruct4!xe: mo'b al"!x&0esp1
initstruct4!x#$: mo'l !x#!0ebp1"eax
initstruct4!x#-: addl ,!x$"eax
initstruct4!x#8: mo'l eax"!x80esp1
initstruct4!x#c: mo'sBl !x#&0ebp1"eax
initstruct4!x$!: addl ,!x%"eax
initstruct4!x$%: mo'B ax"!xc0esp1
initstruct4!x$8: mo'l !x#80ebp1"eax
initstruct4!x$b: addl ,!x&"eax
initstruct4!x$e: mo'l eax"!x#!0esp1
initstruct4!x%$: leal !x#&0esp1"eax
initstruct4!x%6: pshl !x#c0ebp1
initstruct4!x%*: pshl !eax
initstruct4!x%a: call Cstrcp;7
initstruct4!x%f: addl ,!x8"esp
initstruct4!x&$: mo'b ,!x&#"!x$80esp1
initstruct4!x&.: mo'l ,!x!"!x$c0esp1
initstruct4!x&f: pshl "0x2c
initstruct4!x-#: leal !x80esp1"!eax
initstruct4!x--: pshl !eax
initstruct4!x-6: mo'l !x80ebp1"!eax
initstruct4!x-*: pshl !eax
initstruct4!x-a: call Cmemcp;7
initstruct4!x-f: mo'l ebp"esp
initstruct4!x6#: popl ebp
initstruct4!x6$: ret
initstruct: pus/l ebp
initstruct4!x#: mo'l esp"ebp
initstruct4!x%: pus/l ebx
initstruct4!x&: subl ,!x%c"esp
initstruct4!x.: mo'b !xc0ebp1"al
initstruct4!xa: incl eax
initstruct4!xb: mo'b al")!x%80ebp1
initstruct4!xe: mo'l !x#!0ebp1"eax
initstruct4!x##: addl ,!x$"eax
initstruct4!x#&: mo'l eax")!x%&0ebp1
initstruct4!x#.: mo'l !x#&0ebp1"eax
initstruct4!x#a: addl ,!x%"eax
initstruct4!x#d: mo'B ax")!x%!0ebp1
initstruct4!x$#: mo'l !x#80ebp1"eax
initstruct4!x$&: addl ,!x&"eax
initstruct4!x$.: pshl !x#c0ebp1
initstruct4!x$a: mo'l eax")!x$c0ebp1
initstruct4!x$d: leal )!x$80ebp1"!eax
initstruct4!x%!: pshl !eax
initstruct4!x%#: call Cstrcp;7
initstruct4!x%6: addl ,!xc"esp
initstruct4!x%*: pshl "0x2c
initstruct4!x%b: leal )!x%80ebp1"!ebx
initstruct4!x%e: pshl !ebx
initstruct4!x%f: pshl !x80ebp1
initstruct4!x&$: mo'b ,!x&#")!x#&0ebp1
initstruct4!x&6: mo'l ,!x!")!x#!0ebp1
initstruct4!x&d: call Cmemcp;7
initstruct4!x-$: addl ,!x#!"esp
initstruct4!x--: mo'l )!x&0ebp1"ebx
initstruct4!x-8: lea'e
initstruct4!x-*: ret
3he 6.bit version doesn>t sho= conce)tual differences, =hat holds true for local
variables in "2bit mode still a))lies to 6.bit mode.
".Assembly <anguage on x86 )latforms 6
'.8.'.0lobal &ariables
Again changing the sourcecode slightly/
extern sts6t glob6stW
'oid initstruct0
sts6t Ei6nxt"
c/ar i6c"
long i6l"
s/ort i6s"
int i6i"
c/ar Ei6name
1
V
glob6st.s6c [ i6c 4 #W
glob6st.s6l [ i6l 4 $W
glob6st.s6s [ i6s 4 %W
glob6st.s6i [ i6i 4 &W
strcp;0glob6st.s6name" i6name1W
glob6st.s6name2$!3 [ ]H]W
glob6st.s6nxt [ i6nxtW
X
3his exam)le serves =ell to sho= the difference bet=een local variables Fon the stac$G
and global variables Fon the hea)G. (t also illustrates the difference bet=een )osition6
inde)endent and regular code for accessing globals.
Sun 8or9shop cc> !"bit> non*I, Sun 8or9shop cc> !"bit> -Kpic
initstruct: pus/l ebp
initstruct4!x#: mo'l esp"ebp
initstruct4!x%: andl ,!xfffffff!"esp
initstruct4!x6: mo'sbl !xc0ebp1"eax
initstruct4!xa: incl eax
initstruct4!xb: mo'b al"Cg6s7
initstruct4!x#!: mo'l !x#!0ebp1"eax
initstruct4!x#%: addl ,!x$"eax
initstruct4!x#6: mo'l eax"Cg6s4!x&7
initstruct4!x#b: mo'sBl !x#&0ebp1"eax
initstruct4!x#f: addl ,!x%"eax
initstruct4!x$$: mo'B ax"Cg6s4!x87
initstruct4!x$8: mo'l !x#80ebp1"eax
initstruct4!x$b: addl ,!x&"eax
initstruct4!x$e: mo'l eax"Cg6s4!xc7
initstruct4!x%%: pshl !x#c0ebp1
initstruct4!x%6: pshl ,Cg6s4!x#!7
initstruct4!x%b: call Cstrcp;7
initstruct4!x&!: addl ,!x8"esp
initstruct4!x&%: mo'b ,!x&#"!x$&
initstruct4!x&a: mo'l !x80ebp1"eax
initstruct4!x&d: mo'l eax"Cg6s4!x$87
initstruct4!x-$: mo'l ebp"esp
initstruct4!x-&: popl ebp
initstruct4!x--: ret
initstruct: pus/l ebp
4!x#: mo'l esp"ebp
4!x%: andl ,!xfffffff!"esp
4!x6: pus/l ebx
4!x.: pus/l esi
4!x8: call Cinitstruct4!xd7
4!xd: popl ebx
4!xe: addl ,6N?<:H?6<@@SET6TH:?E64#"
ebx
4!x#&: mo'sbl !xc0ebp1"eax
4!x#8: incl eax
4!x#*: mo'l g6s`N<T0ebx1"esi
4!x#f: mo'b al"0esi1
4!x$#: mo'l !x#!0ebp1"eax
4!x$&: addl ,!x$"eax
4!x$.: mo'l eax"!x&0esi1
4!x$a: mo'sBl !x#&0ebp1"eax
4!x$e: addl ,!x%"eax
4!x%#: mo'B ax"!x80esi1
4!x%-: mo'l !x#80ebp1"eax
4!x%8: addl ,!x&"eax
4!x%b: mo'l eax"!xc0esi1
4!x%e: pshl !x#c0ebp1
4!x&#: leal !x#!0esi1"!eax
4!x&&: pshl !eax
4!x&-: call Cstrcp;7
4!x&a: addl ,!x8"esp
4!x&d: mo'b ,!x&#"!x$&0esi1
4!x-#: mo'l !x80ebp1"eax
4!x-&: mo'l eax"!x$80esi1
4!x-.: popl esi
75 ".Assembly <anguage on x86 )latforms
Sun 8or9shop cc> !"bit> non*I, Sun 8or9shop cc> !"bit> -Kpic
4!x-8: popl ebx
4!x-*: mo'l ebp"esp
4!x-b: popl ebp
4!x-c: ret
2egular code Fnot ex)licitly )osition6inde)endentG in "2bit x86 uses direct addressing
Fi.e. "2bit )ointersG to access global variables.
3he $ey )oint to understanding )osition6inde)endent code in "2bit is the 9lobal "ffset
+able F'43G. 3his is the memory location =here 1(! code stores global data structures.
Ee see in the code/
1. 0ince 1(! code can be )ut any=here into memory =ithout the dynamic lin$er;loader
having to do relocation, a 1(! function =ill need to/
determine its o=n load address. 3he sho=n code does this via/
call Cinitstruct4!xd7
popl ebx
3his ?call yourself@ is ty)ical for )osition6inde)endent code on architectures that
don>t allo= the use of the )rogram counter Feip in "2bit x86G for relative
addressing. 3he code sim)ly reads out the current )rogram counter.
add the offset bet=een code location and '43 location to that. 3hat>s =hy it does/
addl ,6N?<:H?6<@@SET6TH:?E64#"ebx
3his code )uts the base address of the 'lobal 4ffset 3able into ebx % and it =ill
be $e)t there over the lifetime of this function Fat leastG.
2. 4nce the '43 location has been determined, addresses of global variables that are
no= =ithin the '43 can be calculated relative to Yebx. Ee see in the exam)le/
mo'l g6s`N<T0ebx1"esi
After that, the start address of the global data structure is $no=n. #embers =ithin
are u)dated relative to 4...0esi1.
7ue to this overhead, and the need to $ee) the '43 address in ebx Floosing one
general6)ur)ose registerG, 1(! code in "2bit x86 is significantly slo=er than non61(!.
6.bit x86 on the other hand $no=s rip6relative addressing. 3his sim)lifies 1(! code
so much that both gcc and 0un Eor$sho) cc $ill al$ays create position!independent
code for 6.bit x86, even =ithout ex)licitly re9uesting it/
-7bit> Sun 8or9shop cc -7bit> 4?6 gcc
initstruct: pus/+ rbp
initstruct4!x#: mo'+ rsp"rbp
initstruct4!x&: sub+ ,!x8"rsp
initstruct4!x8: pus/+ r#$
initstruct4!xa: mo'+ rdi"r#$
initstruct4!xd: mo'+ rdx"r#!
initstruct4!x#!: mo'sbl sil"eax
initstruct4!x#&: incl eax
initstruct4!x#6: mo'b al"g6s0rip1
initstruct4!x#c: add+ ,!x$"r#!
initstruct4!x$!: mo'+ r#!"
g6s4!x80rip1
initstruct4!x$.: mo'sBl cx"eax
initstruct4!x$a: addl ,!x%"eax
initstruct4!x$d: mo'B ax"
g6s4!x#!0rip1
initstruct4!x%&: addl ,!x&"r8d
initstruct: pus/+ rbp
initstruct4!x#: incl esi
initstruct4!x%: add+ ,!x$"rdx
initstruct4!x.: addl ,!x%"ecx
initstruct4!xa: addl ,!x&"r8d
initstruct4!xe: mo'+ rsp"rbp
initstruct4!x##: pus/+ rbx
initstruct4!x#$: mo'+ rdi"rbx
initstruct4!x#-: mo'+ ,g6s4!x#8"!rdi
initstruct4!x#c: sub+ ,!x8"rsp
initstruct4!x$!: mo'b sil"g6s0rip1
initstruct4!x$.: mo'+ r*"!rsi
initstruct4!x$a: mo'+ rdx"
g6s4!x80rip1
initstruct4!x%#: mo'B cx"
g6s4!x#!0rip1
initstruct4!x%8: mo'l r8d"
".Assembly <anguage on x86 )latforms 71
-7bit> Sun 8or9shop cc -7bit> 4?6 gcc
initstruct4!x%8: mo'l r8d"
g6s4!x#&0rip1
initstruct4!x%f: lea+ g6s4!x#80rip1"
!rdi
initstruct4!x&6: mo'+ r*"!rsi
initstruct4!x&*: xorl eax"eax
initstruct4!x&b: call Cstrcp;7
initstruct4!x-!: mo'b ,!x&#"
g6s4!x$c0rip1
initstruct4!x-.: mo'+ r#$"
g6s4!x%!0rip1
initstruct4!x-e: pop+ r#$
initstruct4!x6!: mo'+ rbp"rsp
initstruct4!x6%: pop+ rbp
initstruct4!x6&: ret
g6s4!x#&0rip1
initstruct4!x%f: call Cstrcp;7
initstruct4!x&&: mo'+ rbx"
g6s4!x%!0rip1
initstruct4!x&b: mo'b ,!x&#"
g6s4!x$c0rip1
initstruct4!x-$: add+ ,!x8"rsp
initstruct4!x-6: pop+ rbx
initstruct4!x-.: lea'e
initstruct4!x-8: ret
3he 0un Eor$sho) cc code is fully 1(!, =hile gcc>s code generator )robably contains a
small bug in this case. 3he instruction used by gcc/
initstruct4!x#-: mo'+ ,g6s4!x#8"!rdi
=hich loads the first argument for strc)yFG is &43 using rip6relative addressing. 3he
version the 0un Eor$sho) com)iler uses/
initstruct4!x%f: lea+ g6s4!x#80rip1"!rdi
achieves the same % but in the desirable )osition6inde)endent =ay.
Cor 0un Eor$sho) cc, FnotG using )kpic ma$es no difference to the generated code in
6.bit x86. Cor '&* gcc, )fpic resorts to the FbadG "2bit6style behaviour of
referencing global data relative to 4...0ebx1, and only re)laces the load of the '43
base address =ith rip6relative addressing.
72 ".Assembly <anguage on x86 )latforms
'.>.Compiler help for deb!gging #()6* ode
3he biggest difference bet=een A#76. and i"86 assembly code is the =ay arguments
are )assed.
i"86 )asses arguments on the stac$, in descending order.
A function For a debugger, )ost6mortemG can access its arguments relative to the
frame)ointer, at &Earg
>
0ebp1.
A#76. )asses the first six arguments in registers rdi, rsi, rdx, rcx, r8
and r*. 4nly arguments )ast the sixth end u) on the stac$, at 8Earg
>)6
0rbp1.
(t>s u) to the function =here it $ee)s its arguments, i.e. =hether it leaves them
in the argument registers, moves them to nonvolatile registers, or )uts them
onto the stac$.
A debugger has no sim)le =ay of figuring out =here in the stac$ the arguments
finally end u) Fif at allG.
0ource6level debugging for a))lications of course solves this )roblem, since com)lete
source6level debugging data contains the information about stac$frame layout. -ut this
is too heavy=eight for many )ur)oses, and ina))ro)riate for $ernel debugging.
3he section on ?2egister <ifecycle@ has already sho=n that argument )assing in
registers doesn>t necessarily remove the need to have co)ies of these arguments in the
stac$ some$here during the ?lifetime@ of the function to =hich a given argument =as
)assed to. (n the vast maBority of cases, anything but very sim)le =ra))er functions
=ill end u) having their arguments in the stac$, because/
1. 3he function uses its argumentFsG again after having called another function
itself and therefore needs to ma$e them ?)ermanent@ 6 ma$ing function calls
destroys the contents of the argument registers.
2. 3he function>s active =or$ing set of variables is larger than the number of
available registers, and it therefore moves the arguments out of the =ay in
order to use the argument registers for other )ur)oses.
0o there often is need for A#76. assembly code to sa#e its arguments into the stac$
some$here. And this can be ta$en advantage of.
(n order to ma$e this usable for a debugger to find function arguments automatically,
=e need to instruct the com)iler to/
ma$e some$here into a defined place $ithin the stackframe of the function
al$ays )erform argument saving at entry to the function.
(n fact, #icrosoft for the Eindo=s;x6. A-( has s)ecified this behaviour, by defining
that the first four arguments are )assed in registers, but the calling function also has
to reserve stac$s)ace for them. (.e. the Eindo=s;x6. A-( s)ecifies/ ?(f you =ant to
save your argument registers to the stac$, save them right here 6 the caller has
allocated this s)ace for you...@
3he *&(+ A-( for A#76. does not mandate such behaviour. (m)lementing it is
therefore u) to the com)iler F=hich is not re9uired to do itG % and the s)ace =here the
arguments =ill be )ut in must be in the ?local variables@ section of the stac$frame, not
in the ?arguments@ section as on Eindo=s;x6., because the )rere9uisite for the caller
to reserve s)ace for the arguments doesn>t exist on *&W+;A#76..
2ecent *&W+ com)ilers for x6. F0un Eor$sho) 15.1, and gcc via )atches since August
2555G can be instructed to create function )rologue code that saves argument
registers into the stac$, at the beginning of a function>s stac$frame.
3he big )roblem one is faced =ith =hen debugging A#76. code on assembly level,
".Assembly <anguage on x86 )latforms 7"
namely finding arguments in stac$traces, becomes almost as trivial as =ith classical
"2bit i"86 code 6 =hen the )sa'e6args com)iler o)tion F)msa'e6args on gccG has
been used.
All arguments are accessible at $no=n locations relative to the frame)ointer for the
function/
argument !"bit A i!'- )sa'e6args" -7bit A amd-7
first DLE
second DE
third D3E
fourth DFE
fifth D*E
si%th DBE
se#enth DJE
eigth DJE
... D@E
!x80ebp1
!xc0ebp1
!x#!0ebp1
!x#&0ebp1
!x#80ebp1
!x#c0ebp1
!x$!0ebp1
!x$&0ebp1
0x4#$%+1&0ebp1
)!x80rbp1 rdi
)!x#!0rbp1 rsi
)!x#80rbp1 rdx
)!x$!0rbp1 rcx
)!x$80rbp1 r8
)!x%!0rbp1 r*
!x#!0rbp1
!x#80rbp1
0x8#$%'5&0rbp1
!om)iling code =ith )sa'e6args allo=s bac$traces =ith arguments even from sim)le
debuggers that don>t do code flo= tracing to locate the arguments.
7. ".Assembly <anguage on x86 )latforms
Illustration 3 ! 5)D'* 1tack ?ayout. re,uesting the compiler to sa#e args to the
stack
stac$)ointer at start
"rame 2
nd
"unction
stac$ gro=th,
more function
calls
r
e
t
.

a
d
d
r
e
s
s

t
o

f
u
n
c
.

1
"rame 1
st
"unction
current
stac$)ointer
s
a
v
e
d

f
r
a
m
e
p
t
r

f
u
n
c
.

1
a
r
g
[
6

t
o

f
u
n
c
.

2
a
r
g
[
7

t
o

f
u
n
c
.

2
a
r
g
[
5

t
o

f
u
n
c
.

2
a
r
g
[
1

t
o

f
u
n
c
.

2
a
r
g
[
2

t
o

f
u
n
c
.

2
a
r
g
[
"

t
o

f
u
n
c
.

2
a
r
g
[
.

t
o

f
u
n
c
.

2
a
r
g
[
5

t
o

f
u
n
c
.

2
caller6saved/ arg[6 ff.
callee6saved/ arg[5..5
only if )sa'e6args is used A
'.>.1.Code samples with and witho!t :sa&e?args
As an illustration ho= this behaviour changes function )rologues, let>s loo$ at an
exam)le.
amd-7 binary> =ith )sa'e6args amd-7 binary> classical
/sfs6getpage: pus/+ rbp
/sfs6getpage4#: mo'+ rsp"rbp
/sfs6getpage4&: sub+ ,!x$8"rsp
/sfs6getpage48: pus/+ rbx
/sfs6getpage4*: pus/+ r#$
/sfs6getpage4!xb: pus/+ r#%
/sfs6getpage4!xd: pus/+ r#&
/sfs6getpage4!xf: pus/+ r#-
/sfs6getpage4!x##: mo'+ rdi")!x80rbp1
/sfs6getpage4!x#-: mo'+ rdi"r#&
/sfs6getpage4!x#8: mo'+ rsi")
!x#!0rbp1
/sfs6getpage4!x#c: mo'+ rsi"r#%
/sfs6getpage4!x#f: mo'+ rdx")
!x#80rbp1
/sfs6getpage4!x$%: mo'+ rdx"r#$
/sfs6getpage4!x$6: mo'+ rcx")
!x$!0rbp1
/sfs6getpage4!x$a: mo'+ rcx"r#-
/sfs6getpage4!x$d: mo'+ r8")!x$80rbp1
/sfs6getpage4!x%#: mo'+ r8")!x%80rbp1
/sfs6getpage4!x%-: mo'+ r*")!x%!0rbp1
/sfs6getpage4!x%*: mo'+ r*")!x&80rbp1
/sfs6getpage4!x%d: mo'+ !x#!0r#&1"rbx
/sfs6getpage4!x&#: mo'l !x$!0rbp1"eax
[ ... ]
/sfs6getpage4!xfb: mo'+ !x#!0rbp1"r8
/sfs6getpage4!xff: mo'+ !x#80rbp1"r*
/sfs6getpage4!x#!%: mo'+ !x$80rbp1"r#!
[ ... ]
/sfs6getpage: pus/+ rbp
/sfs6getpage4#: mo'+ rsp"rbp
/sfs6getpage4&: sub+ ,!x-8"rsp
/sfs6getpage48: pus/+ rbx
/sfs6getpage4*: pus/+ r#$
/sfs6getpage4!xb: pus/+ r#%
/sfs6getpage4!xd: pus/+ r#&
/sfs6getpage4!xf: pus/+ r#-
/sfs6getpage4!x##: mo'+ rdi"r#&
/sfs6getpage4!x#&: mo'+ rsi"r#%
/sfs6getpage4!x#.: mo'+ rdx"r#$
/sfs6getpage4!x#a: mo'+ rcx"r#-
/sfs6getpage4!x#d: mo'+ r8")!x80rbp1
/sfs6getpage4!x$#: mo'+ r*")!x#80rbp1
/sfs6getpage4!x$-: mo'+ !x#!0r#&1"rbx
/sfs6getpage4!x$*: mo'l !x$!0rbp1"eax
[ ... ]
/sfs6getpage4!xe%: mo'+ !x#!0rbp1"r8
/sfs6getpage4!xe.: mo'+ !x#80rbp1"r*
/sfs6getpage4!xae: mo'+ !x$80rbp1"r#!
[ ... ]
!ode generated by the same com)iler =ithout and =ith the )sa'e6args o)tion only
differs in
the amount of s)ace allocated on the stac$
F6 more =ords, 5x"5 bytes for the six argument registersG,
the instructions that save the argument registers into the stac$
the rbp6relative offsets used for local variables, =hich are shifted by !x%!.
".Assembly <anguage on x86 )latforms 75
*.(emory and Pri&ilege
(anagement on x86
Crom ?3he 3ao of 1rogramming@/
+hus spake the master programmer:
NHhen program is being tested. it is too late to make design changes.N
Advanced o)erating systems se)arate several concurrently running a))lications from
each other, and $ee) the o)erating system $ernel isolated from a))lications.
3his )uts t=o basic re9uirements on the !1*/
1. !onfigurable address s)aces F?!ontexts@G. 3=o a))lications may not access the
same memory unless an ex)licit ?sharing@ re9uest =as made. And li$e=ise,
a))lications may not usually access the o)erating system $ernel>s data, nor should
unless deliberately re9uested the $ernel modify memory in use by a given
a))lication.
(n short, modern o)erating systems re9uire a ##*.
2. 1rivileged execution. A))lications cannot be allo=ed to modify !1* state that is
critical to the o)erating system. 4nly the $ernel and its device drivers $no= ho= to
access hard=are, and only the $ernel may grant memory;device access to
a))lications via controlled interfaces. (n other =ords, =e need/
1rivilege levels.
3he $ernel =ill run in )rivileged mode and have access to all !1* instructions ;
all hard=are including those that are crucial to system integrity.
A))lications, on the other hand, =ill run un)rivileged and be )revented from
?messing u)@ the system.
1rivilege s=itching mechanisms.
!ontrolled interfaces Fsystem calls, exce)tions, interru)tsG are re9uired to )ass
execution from un)rivileged mode Fa))licationsG to )rivileged F$ernelG.
!1*s in the x86 family )rovide the abovementioned features if o)erating in the
:rotected )ode.
..#emory and 1rivilege #anagement on x86 77
*.1.The x86 proteted mode - pri&ilege management
(ntel =as late to introduce a model for )rogram execution at different )rivilege levels.
&ot until 182 =hen the 85286 =as released did (ntel6com)atible !1*s $no= about a
fully6functional model for sto))ing user code from executing arbitrary instructions or
)erforming other critical actions that could com)romise e.g. the integrity of an
o)erating systems. 3he conce)t of user;super#isor mode that other architectures had
for a long time already even bac$ in 182 has not been a designed )art of the x86
architecture.
Ehen (ntel finally im)lemented )rivileges they chose a multi6layer model for it,
allo=ing for t=o intermediate )rivilege levels bet=een user mode and fully!pri#ileged
super#isor mode.
(ntel calls this model :rotected )ode. (t theoretically allo=s for fine6grained control
about =ho can execute instructions that modify critical system state, or modify
memory;)eri)heral state =hose consistency is crucial for the integrity of an o)erating
system.
3he (ntel term for these execution modes is 2ings. 3here are four/
+ing :
3his mode allo=s unrestricted access to all !1*;hard=are ca)abilities;resources.
2ing 1
3his is meant to be used for drivers that can get by =ith unrestricted access to a
78 ..#emory and 1rivilege #anagement on x86
(llustration 1 6 1rotected #ode usage, as imagined by (ntel
+$.0 '
User Applications, unprivileged code
+
$
.
0

1































6
o
r

#
s
e

b
0

d
r
i
*
e
r
s
















+
$.0
"












































3
,
8
;
e
r
n
e
l

s
e
r
*
i
c
e
s
+$.0 @
one ring
to rule them all
ore ,ernel mode
an do anything
limited set of !1*;hard=are ca)abilities;resources.
2ing 2
3his is su))osed to be used by services of the o)erating system =hich can be
im)lemented e.g =ith the use of )rivileged instructions but =ithout )rivileged
access to hard=are;memory on a large scale.
+ing !
A))lication )rograms that need strong isolation against each other =ill use ring ".
(ntel =asn>t the first to introduce a fine6)rivileges execution model 6 a *0 military !1*
design from the late 75s F#(<603761755G has 16 FAG )rivilege levels. (t never gained
momentum. 4n )a)er, the idea of building sandbo%es even for o)erating6system code
has some benefits. -ut the actual hard=are im)lementation for the *0 military>s !1*
=as too com)lex;heavy=eight for its time, =hile the stri))ed6do=n model by (ntel
reached mar$et far too late. (ntel introduced rings of execution at a time =hen most
o)erating systems =ere already designed around hard=are that only had the all6or6
nothing user;su)ervisor model. 3hat>s one reason =hy all modern o)erating systems
for x86 colla)se ring 5..2 and use only t=o modes/
+ing : 6 o)erating system, drivers
+ing ! 6 a))lication )rograms
Additionally, =hat may =ell have contributed to the fact that the fine6grained )rivilege
control of the 1rotected #ode =as never really used to its full ca)abilities is the actual
im)lementation of these features.
*.1.1.%&ol!tion of pri&ilege and memory management
on x86
3he 8586 16bit !1* had no conce)t of )rivilege =hatsoever. Every code =as allo=ed
to use all instructions and modify !1* state that normally =ould be considered to
?belong@ to an o)erating system only.
-ut the 8586 had a rudimentary memory management conce)t. 3he !1* and all its
registers, as =ell as direct address offsets, =ere 16bit only F6.$-G but yet the
)rocessor could handle 1#- of )hysical memory.
#any 16bit !1*s had such ca)abilities % im)lemented via a mechanism usually called
bank s$itching. 4ne =ould )rogram a memory controller register =ith ?the ban$ of
memory@ Fi.e. the 6.$- =indo= out of the larger )hysical addressing rangeG that 16bit
memory accesses could ma) to.
3his is inflexible if multi)le 16bit chun$s are concurrently in use. !onsider co)ying
memory/ s=itch to ban$ A, move 16bit from mem to register, s=itch to ban$ -, move
register to mem, s=itch to ban$ A, ...
(ntel therefore )rovided segmentation and in the 8586. 3his does mean nothing else
than subdividing the V16bit )hysical address s)ace into an array of 16bit F6.$-G ban$s
=hich (ntel decided to call segments, and ma$ing multi)le of these accessible
concurrently by the use of segment registers. (n other =ords/ 3he 8586>s memory
controller su))orted multi)le ban$s;segments of memory at the same time.
3hree of them use very common terms/
code segment, cs 6 instruction addresses Fcode locationsG.
data segment, ds 6 data addresses Fdirect or indirect via ax;bx;cx;dxG
stac$ segment, ss 6 the stac$ Fbase for sp;bp6relative addressesG
..#emory and 1rivilege #anagement on x86 7
3he fourth one =as associated =ith s)ecific instructions im)lementing many of the
mem...;str... function family in hard=are/
string segment, es 6 data addresses Findirect via string src;dest si;diG
(n the 8586, the segment registers =ould sim)ly contain the high . bit of the )hysical
address, and the ma))ing bet=een segment (7 Fcontents of a segment registerG and
)hysical memory location of the 6.bit segment =as static 1/1.
(n addition to the above implicit use of the segment registers, the 8586 allo=ed
ex)licit segment overrides. 3his is useful for segment6to6segment co)y, =hich =as then
done using a method li$e/
mo'B es:0dx1"ax
mo'B ax"0dx1
=hich co)ies the value at offset dx from the Fnon6default, therefore es: )refixG
string segment to the default data segment. As said, unli$e other 16bit !1*s, no ban$
s=itching =as needed.
3he notation segment:offset is called far pointer by (ntel.
3he segmentation mechanism in the 8586 =asn>t )rogrammable, i.e. an o)erating
system couldn>t relocate segments. 4f course, due to the lac$ of )rivileges neither =as
there a conce)t of =rite )rotection or )rivileged6only access.
(ntel )rovided these ca)abilities in the 85286 via the :rotected )ode. 3he )rotected
mode/
re)laced the static segment numbers that =ere the contents of segment registers on
the 8586 =ith so6called segment selectors.
made the association bet=een segments and )hysical memory )rogrammable via
ma))ing tables % the segment numbers no= index a table, and the entry there
)rovides the actual segment base address.
allo=ed ?re9uestors@ Fcode using the segment registerG to s)ecify a )rivilege level
for memory access through this segment FselectorG
allo=ed ?re9uestors@ to select =hich of the t=o translation tables Flocal or globalG
the !1* should use to get the )hysical location of the segment.
3his is, in generic terms, of course a memory management unit =ith t=o contexts.
0ince the !1* =as still 16bit and therefore no more than 6.$- =ere accessible
=ithout using the segmentation mechanism, this seemed li$e a straightfor=ard =ay of
im)lementing virtual memory management ca)abilities.
85 ..#emory and 1rivilege #anagement on x86
Illustration 3 ! 6memory management7 on the &L&' processor
0 15 16 19 20 31
segO 'bit address offset DunusedE
3Lbit physical address
-ut unfortunately (ntel tied !1* )rivilege management to these Descriptor +ables.
3hese are not only used for )rogrammable segmentation as memory management
mechanism, but the descri)tor table entries, called segment descriptors, are also used
for )rivilege management. 0egment descri)tors/
declare the segment )rivilege level Fi.e. =hich ring this is accessible fromG
define access attributes F)resent, r;= or readonly, executable, ...G
are aliased to data structures called gate descriptors that redirect execution
bet=een code segments Fi.e. executable segmentsG of different )rivilege levels.
3his leads to the odd situation that x86 descri)tor tables contain t=o very different
$inds of entries/
segment descriptors F=hich )rovide base address, siKe and )rivilege levelG for
memory management and )rivilege declaration, and
gate descriptors F=hich su))ly a call destination/ cs:functionG for )rivilege
s=itching.
A 16bit )rotected mode setu) uses hundreds of segments % for the ##* functionality.
*.1.".'"bit Proteted (ode
(n "2bit mode, the memory management facilities of the )rotected mode turned
ina))licable for t=o reasons/
2egisters, addresses and address offsets =ere no= "2bit =ide, there =as no )oint
anymore to force )rogrammers into using and managing segment registers for
accessing more than 16bit;6.$- of continuous memory.
3he single6indirection table method that seemed still a))licable for translating
bet=een ?virtual@ 16bit far )ointers to )hysical addresses via the descri)tor tables
of course brea$s do=n if the system can su))ort .'- )hysical memory. 3he =ay the
..#emory and 1rivilege #anagement on x86 81
Illustration F ! 'bit protected mode on the i&L3&'
Local Descriptor
Table
base:si8e
base:si8e
base:si8e
base:si8e
base:si8e
0 15 18 19 31
'bit address offset
2.bit )hysical address F16#-G
4
base address
p
r
i
#
.
+
+
Global Descriptor
Table
base:si8e
base:si8e
base:si8e
base:si8e
t
t

P

L
t
t

P

segment
b
a
s
e

a
d
d
r
e
s
s
base:si8e
gdtr
ldtr
segment selector is laid out Ft=o bits for )rivilege, the table ty)e bit, and 1" bit for
the table indexG does only allo= 812 descri)tor table entries, but at 6.$- )er
segment one needs 655"5 F6.$G to cover the entire "2bit )hysical address s)ace.
"2bit )rograms therefore =ere su))lied =ith a =holly se)arate "2bit ##* =hich =ill
be described in section ".". 0egmentation is no longer used for address space
separation. the ne= F"2bitG ##* ta$es over this tas$.
0egment descri)tors in "2bit mode are su))osed to be set u) to allo= flat addressing,
=here the ?near@ "2bit )art of the .8bit logical address Fi.e. the far )ointer including
the im)licitly used segment registerG ma)s 1/1 to the "2bits of the #irtual address. 3his
tric$ is accom)lished by setting the base address to &*<< and the segment siKe to
.'- in those segment descri)tors.
3he effect is to bypass segmentation/
3he )rotected mode in "2bit is therefore reduced to/
1. 7eclare the )rivilege levels to use. Each ring to be used needs t=o segment
descri)tors/
one flat code segment descri)tor, and
one flat data segment descri)tor.
All a))lications =ould share the same set of code;data segment descri)tors. 0ince
all these segments =ere flat Fand therefore overla)G, the segment registers contain,
at all times, only one out of t=o configurations/
Segment +egister value in 9ernel mode value in user mode
cs ring 5 code segment ring " code segment
ds;es;ss ring 5 data segment ring " data segment
82 ..#emory and 1rivilege #anagement on x86
Illustration * ! creating flat DunsegmentedE F3bit address spaces on the &LF&'
Local Descriptor
Table
base:si8e
base:si8e
base:si8e
base:si8e
base:si8e
0 31 15
F3bit DlogicalE address
F3bit #irtual address
base address
p
r
i
#
.
+
+
Global Descriptor
Table
base:si8e
base:si8e
base:si8e
base:si8e
t
t

P

L
t
t

P

segment
b
a
s
e

a
d
d
r
e
s
s
base:si8e
gdtr
ldtr
0 1 2 3
>Q??
DF3bitE physical address
"2bit
##*
2. 1rovide a )rivilege s=itching mechanism, i.e. at least one system call gate.
A ty)ical "2bit )rotected mode setu) therefore is very sim)le/
Even using a <ocal 7escri)tor 3able at all is o)tional % it>s )ossible to )ut both user
and $ernel mode code;data segments and syscall gate into the 'lobal 7escri)tor 3able.
&ote that on x86, e%ecutability is a )ro)erty of the code segment. 3he classical "2bit
x86 ##* does not have an attribute bit for ?is this )age executable J@ 6 only )ost6
A#76. ##*s $no= about a ?&+@ )age attribute bit. A certain memory location is
executable if there exists a code segment that covers it. !onse9uently, if =e let code
and data segments overla) Fand there are very good reasons for this % do you =ant
function addresses to be conce)tually different from any other address JG, everything
is executable.
4n classic x86 )latforms using the "2bit )rotected mode =ith flat segments, every
address is executable A
*.1.'.System segments
3he 1rotected mode uses t=o s)ecial segment descri)tor ty)es Fsystem descri)torsG for
control )ur)oses/
1. 3he ?ogical Descriptor +able in fact is a Fnon6flatG segment. ldtr therefore doesn>t
contain a memory location Fli$e gdtr doesG, but a segment selector % the local
descri)tor table register is a segment register, =ith a s)ecial rule that it may only
contain selectors =hose TT bit is clear Fi.e. =hich index the '73G.
3he original idea =as to use the '73 for $ernel segments and the <73 for those of
a))lications, and o)erating systems $ee)ing trac$ of these user contexts by creating
one <73 )er a))lication.
2. 3he +ask 1tate 1truct F300G is another ty)e of system descri)tor.
300 embodies the idea of a ?context@ in hard=are.
(n the limited =ay ho= most o)erating systems set u) the )rotected mode, the role of
the 300 is to su))ly the !1* =ith stac$)ointer locations for the various rings of
)rivilege.
3he "2bit mode 300 is more com)licated because it contains a bac$ing store s)ace
..#emory and 1rivilege #anagement on x86 8"
Illustration B ! typical F3bit protected mode setup
/ocal Descriptor
.able
user cs
user ds/es/ss
system call gate
Global Descriptor
Table
kernel %ds/%es/%ss
kernel cs
?D+ base
F3bit +11
"2bit flat
address s)ace
base >Q??
siKe .'-
!x!!!!!!!!
!xffffffff
s;scall6/andler01
for the general6)ur)ose and segment register set as =ell as the set of stac$)ointers
for the various )rivilege levels/
struct tss V
uint#66t tss6linkW /E #6)bit prior TSS selector E/
uint#66t tss6rs'd!W /E reser'ed" ignored E/
uint%$6t tss6esp!W
uint#66t tss6ss!W
uint#66t tss6rs'd#W /E reser'ed" ignored E/
uint%$6t tss6esp#W
uint#66t tss6ss#W
uint#66t tss6rs'd$W /E reser'ed" ignored E/
uint%$6t tss6esp$W
uint#66t tss6ss$W
uint#66t tss6rs'd%W /E reser'ed" ignored E/
uint%$6t tss6cr%W
uint%$6t tss6eipW
uint%$6t tss6eflagsW
uint%$6t tss6eaxW
uint%$6t tss6ecxW
uint%$6t tss6edxW
uint%$6t tss6ebxW
uint%$6t tss6espW
uint%$6t tss6ebpW
uint%$6t tss6esiW
uint%$6t tss6ediW
uint#66t tss6esW
uint#66t tss6rs'd&W /E reser'ed" ignored E/
uint#66t tss6csW
uint#66t tss6rs'd-W /E reser'ed" ignored E/
uint#66t tss6ssW
uint#66t tss6rs'd6W /E reser'ed" ignored E/
uint#66t tss6dsW
uint#66t tss6rs'd.W /E reser'ed" ignored E/
uint#66t tss6fsW
uint#66t tss6rs'd8W /E reser'ed" ignored E/
uint#66t tss6gsW
uint#66t tss6rs'd*W /E reser'ed" ignored E/
uint#66t tss6ldtW
uint#66t tss6rs'd#!W /E reser'ed" ignored E/
uint#66t tss6rs'd##W /E reser'ed" ignored E/
uint#66t tss6bitmapbaseW /E io permission bitmap base
address E/
XW
3he 6.bit 300 is ?reduced@ to the sim)le role of )roviding stac$)ointers % one for
each higher6)rivileged ring of execution, and a selectable table of se#en interrupt
stackpointers, the FST23/
Dpragma pack0&1
struct tss V
uint%$6t tss6rs'd!W /E reser'ed" ignored E/
uint6&6t tss6rsp!W /E stack pointer CP? [ ! E/
uint6&6t tss6rsp#W /E stack pointer CP? [ # E/
uint6&6t tss6rsp$W /E stack pointer CP? [ $ E/
uint6&6t tss6rs'd#W /E reser'ed" ignored E/
uint6&6t tss6ist#W /E Fnterrupt stack table # E/
uint6&6t tss6ist$W /E Fnterrupt stack table $ E/
uint6&6t tss6ist%W /E Fnterrupt stack table % E/
uint6&6t tss6ist&W /E Fnterrupt stack table & E/
uint6&6t tss6ist-W /E Fnterrupt stack table - E/
8. ..#emory and 1rivilege #anagement on x86
Aesp8Ass for all )rivileged rings
uint6&6t tss6ist6W /E Fnterrupt stack table 6 E/
uint6&6t tss6ist.W /E Fnterrupt stack table . E/
uint6&6t tss6rs'd$W /E reser'ed" ignored E/
uint#66t tss6rs'd%W /E reser'ed" ignored E/
uint#66t tss6bitmapbaseW /E io permission bitmap base
address E/
XW
Dpragma pack01
0ince in the 6.bit mode, all im)licitly6used segments Fcs;ds;es;ssG are flat, it>s
unnecessary to )rovide values for ss in any )rivilege level.
(ntel originally introduced the 300 for hard$are task s$itching. 3he current tas$ is,
li$e the ldtr, a s)ecial segment register called task register FtrG. 3he selector in
there indexes the '73. An o)erating system could have multi)le Fone )er )rocessG 300
segments in the '73, and ?s=itch@ bet=een them by reloading tr. 0uch a tas$ s=itch
=ould save the current state FregistersG to the current 300, and then reload that Fi.e.
all register;segment register contentsG from the ne= 300, ma$ing that current.
Ehile a given tas$ is running Fi.e. a certain 300 being activeG, the 300 )rovides the
!1* =ith the information $here to find kernel stackpointers =hen doing a )rivilege
s=itch.
Hard=are tas$ s=itching has )roven troublesome over time/
the 300 )rovides no means for saving;restoring floating )oint registers or other
register extensions that =ere introduced in the x86 family )ost685"86.
the 300 )rovides no means for an o)erating system to attach ?40 state@ to a tas$.
hard=are tas$ s=itching is !(0! at its =orst % it>s a single !1* instruction but
executing this is horribly slo=. (t>s in fact much slo=er than saving;restoring the
register set manually using sim)le se9uences of instructions.
hard=are tas$ s=itching doesn>t scale to large numbers of )rocesses.
7escri)tor 3ables have siKe limitations % the index )art of a segment selector is only
1"bit and the '73 therefore cannot be larger than 812 entries. -ut 300 segments
must be in the '73, and a limit of Zfe= thousands of threads is belo= =hat x86
!1*s have been able to handle for some generations by no=, even in "2bit.
3his is =hy even (ntel>s manuals today discourage the use of hard=are tas$ s=itching.
A#7 in devising the 6.bit extension therefore decided to limit the use of the 300
=hen running in 6.bit mode to its remaining core )ur)oses/
1. 1rovide stac$)ointers for the various )rivilege levels.
2. 1rovide a mechanism for interru)ts to run on se)arate stac$s.
Hard=are tas$ s=itching is no longer )ossible in 6.bit mode % there>s al=ays one tas$
only, and the o)erating system =ill need to change $ernel stac$)ointers =ithin that
single 300 if it =ishes to use e.g. )er6thread $ernel stac$s.
*.1.*.Pri&ilege swithing
3he x86 )rotected mode, very much unli$e other !1* architectures, does not $no=
any im)licit )rivilege s=itching. 3here is no instruction at all, and no interru)t, tra) or
other event =hich =ill end u) in )rivileged mode % unless the !1* =as )rogrammed
for the s)ecific event to redirect execution to a handler function running =ith higher
)rivileges.
All )rivilege s=itching on x86 )latforms ha))ens through gates. Ehich means the
?rings@ model )robably should better be dra=n li$e this/
..#emory and 1rivilege #anagement on x86 85
A gate is a descri)tor Fi.e. an entry of a descri)tor tableG =hich, instead of base
address and siKe s)ecifies a gate handler address and a target code segment selector.
'ates therefore/
redirect execution to a s)ecific location Fthe gate handlerG in the target cs.
s=itch )rivileges if the target cs )rivilege level is not e9ual to the current cs
)rivilege level.
1rivilege s=itching is done by calling a gate. 'ate calls can be/
e%plicit, by using the far call instruction, lcall, and s)ecifying the segment selector
that indexes the desired gate in the '73 or <73.
implicit, via the Interrupt Descriptor +able F(73G. 3he (73 is s)ecial in the sense
that it only may contain gate descri)tors, and must have exactly 255 entries Fone for
each x86 interru)t numberG. All hard=are exce)tions, faults, tra)s and interru)ts on
x86 are routed via the (73.
#ore details on )rivilege s=itching =ill be given in section ".2.2.
86 ..#emory and 1rivilege #anagement on x86
Illustration ' ! pri#ilege s$itching and gates
R
ING
R
IN
G 1




R
IN
G
2

Ring 3 ! "n#ri$ileged code
Ent ering higher
privilege t hrough
Gat es
*.1.8.6*bit Proteted (ode
3he 6.bit )rotected mode is highly sim)lified. (n fact, the already6described common
)ractice of setting u) the F"2bitG )rotected mode as follo=s/
All im)licitly used segments Fcs and ds;es;ssG are flat
one code and one data segment for ring 5 % $ernel
one code and one data segment for ring " % usermode
0egment regs ds;es;ss are e9ual at all times.
-oth cs and ds;es;ss can only have one of t=o set of values/ $ernel;user.
is made mandatory in 6.bit mode.
3he 6.bit )rotected mode doesn>t care about descri)tor base;siKe values as far as the
corres)onding segment selectors are in cs;ds;es;ss. 3hese segments are
im)licitly flat, and the !1* =ill only use;chec$ the )rivilege level bits % and the ty)e of
the segment. A ty)ical 6.bit x86 )rotected mode setu) uses/
a 6.bit code and a data segment Fone eachG for ring 5, the $ernel
one data segment for ring ", a))lications Fshared by "2;6.bit a))licationsG
one 6.bit code segment for ring ", used by 6.bit a))lications
one "2bit code segment for ring ", used by "2bit a))lications Fcompatibility modeG
All these segments are implicitly flat % the 6.bit x86 !1* ignores base;siKe values in
these descri)tors.
0ystem call and tra) handling changes slightly % see section ".2.
*.1.6.Segment and 0ate )esriptor Formats
*.1.9.The role of segment registers %fs and %gs
3he x86 architecture suffers from the lac$ of general6)ur)ose registers % as sho=n,
there are only eight of them in "2bit mode, and 16 in 6.bit mode, and their contents
are shared bet=een all functions in a )rogram, and bet=een the different levels of
)rivileges Fa )rivilege s=itch doesn>t change any of the general6)ur)ose registers
exce)t for esp;rspG.
-ut there often is need to $ee) some fixed reference, li$e a )ointer to thread!specific
data, in a location that>s 9uic$ly accessible.
!1* architectures =ith many registers at their dis)osal usually s)ecify in the A-( that
one register is su))osed to be set aside for this useN 01A2!, for exam)le, gives g. on
every !1* to hold the address of the current thread.
7oing that on x86 is bad % it>d slo= do=n code significantly. !onsider e.g. the i"86
*&(+ A-(, =hich already s)ecifies fixed roles for esp;ebp Fthe stac$6;frame)ointerG
and ebx Ffor the location of the global offset table in )osition6inde)endent codeG.
3a$ing ebx is bad enough and, as sho=n in cha)ter 2, slo=s do=n )osition6
inde)endent code significantly. -ut ta$ing yet another of the general6)ur)ose registers
a=ay for thread6s)ecific data is a very bad idea, not only because it>d reduce the
number of registers available to only four, but also because it>d )revent running code
from being able to use the full x86 instruction set. All remaining five registers
Feax;ecx;edx;esi;ediG are used im)licitly in some contexts Fecx is the counter
..#emory and 1rivilege #anagement on x86 87
register for loop;rep, eax;edx are )referred o)erand registers for "2 6.
multi)lication;division, and esi;edi are o)erand registers for string instructionsG are
im)licitly used some=here.
3his means another solution is re9uired. (ntel had seen the need for this, and in fact
)rovides a =ay out of the )roblem by su))lying t=o segment registers that are not
im)licitly used for anything 6 fs and gs.
3here are t=o related conce)ts that can be im)lemented using global segments/
1. thread6s)ecific data ; thread6local storage F307;3<0G. 3his means a )er6thread $ey is
used to locate a )iece of data that>s global to a given thread and accessible under
the same $ey from all functions =ithin this thread.
7ifferent threads use different keys to locate ?their@ data. All descri)tor tables Fon
all !1*sG =ill contain a common set of segment descri)tors Fone )er $eyG that locate
the various data sets.
2. !1*6local data in multi)rocessor systems.
3he same key is used by code indifferent of =hat !1* it is running on but
de)ending on that a different set of data is )rovided, by )utting different segment
descri)tors into each !1*>s descri)tor table at the index s)ecified by the common
selector value.
88 ..#emory and 1rivilege #anagement on x86
*.".Traps1 $nterr!pts1 System Calls1 Contexts
*.".1.The $nterr!pt )esriptor Table
As mentioned before, x86 !1*s do not $no= any instruction nor any other event that
im)licitly =ould s=itch the !1* from non)rivileged into )rivileged execution. (nstead,
all events that on other !1*s commonly involve a s=itch into su)ervisor mode /
hard=are interru)ts
tra)s and machine exce)tions
code execution errors Farithmetic faults, undefined;illegal o)codes, brea$)ointsG
)rivilege violation attem)ts Fexecuting )rivileged instructions ; accessing )rivileged
memory from un)rivileged codeG
are )rogrammable on x86 % they are routed through the Interrupt Descriptor +able.
3he (73 is different from '73;<73 in that it can only contain gate descriptors. (n
addition to that, it al=ays contains 255 entries % one for each interru)t vector $no=n
to the x86 !1*.
*.".".Pri&ilege swithes and sta,s
*.".'.Fast system all interfaes
?!lassical@ x86 system calls using a call gate in the <73 and the lcall instruction
have a long latency due to the various descri)tor table loo$u)s that are needed/
A segment loo$u) is )erformed to extract the <73 base address from the <73
segment descri)tor in the '73.
A segment loo$u) is )erformed to extract the gate descri)tor from the <73
A segment loo$u) is )erformed to extract the $ernel code segment base address
from the '73.
4nly then can execution be transferred into the $ernel, and the handler be dis)atched.
A faster method to )erform a system call is using an interrupt gate in the (73 and an
int instruction to issue the system call. 0ince the (73 is no segment, but located
directly in memory via its base address in idtr, this involves one less descri)tor table
loo$u). *sing int instead of lcall is therefore a )referable =ay ho= to )erform
system calls on x86 machines and yields lo=er latency syscalls.
-ut even that is still burdened =ith the overhead of segmentation and descri)tor table
loo$u).
(n a flat memory model as it is used in "2bit and 6.bit )rotected mode, a far pointer
kernel6code6segment:s;scall6/andler contains all of the information re9uired to
)erform the )rivilege s=itch and call the $ernel entry )oint. 3he target F$ernelG code
segment>s )rivilege bits determine that a )rivilege s=itch is re9uested, and since the
$ernel code segment is flat no base address needs to be added to the handler,
segmentation memory translation is a no6o). &o descri)tor table loo$u)s at all are
necessary to derive this.
Ehat>s needed therefore is a =ay to tell the !1*/ Cor )erforming a syscall, call a
..#emory and 1rivilege #anagement on x86 8
s)ecific )redefined far )ointer, i.e./
s=itch to the $ernel code segment Fand raise )rivileges as re9uestedG
run the $ernel>s system call handler given its address.
-oth (ntel and A#7 inde)endently introduced fast system call mechanisms in their
x86 !1*s that allo= this sim)le ?s=itch to )rivileged mode and call that handler@
a))roach % s;senter from (ntel, and s;scall by A#7.
3he s;scall instruction, if available F(ntel !1*s only $no= it if they have the A#76.6
com)atible E#6.3 extensionG, is the )referrable solution because it automatically
saves usermode return addresses and stac$)ointers on entry, and the corres)onding
s;sret instruction can resume execution in userland after the system call from there
directly. (ntel>s s;senter;s;sexit instructions re9uire the caller to )ass return
addresses and usermode stac$)ointers in registers, and the $ernel must manually
restore them before being able to issue s;sexit to return from the system call.
A)art from these im)lementation differences, the actual mechanism to control fast
system calls are similar bet=een the t=o. As an exam)le, the s;scall;s;sret method
=ill be described here.
5 ..#emory and 1rivilege #anagement on x86
*.'.2irt!al (emory (anagement on x86
3he 8586 16bit !1* did not su))ort any form of memory management % the ma))ing
bet=een the u))er 16bits of a ?logical@ FfarG address, i.e. the segment (7, and the
u))er 16bits of the "2bit F=ell % 25bitG )hysical address =as static, 1/1. (n addition, as
mentioned before, the 8586 had no notion of )rivilege and o)erating systems could
neither establish se)arate address s)aces bet=een non)rivileged user a))lications and
)rivileged $ernel code, nor )revent a))lication code from executing instructions that
=ould modify ?critical@ state.
Eith the 85286, (ntel both introduced a mechanism for )rivilege management and
made the ma))ing bet=een segment (7s Fthe far )art of an address, i.e. the u))er
16bitG and )hysical address )rogrammable. (n the 85286 and follo=ing !1*s o)erating
in 16bit mode, the protected mode allo=ed for )rivilege and address s)ace se)aration
by declaring Fnon6overla))ingG user;$ernel code and data segments. 0ince the
association bet=een segment (7s and their F)hysicalG location in memory is fully
)rogrammable, the 16bit )rotected mode im)lemented a sim)le one6level ##*, =ith
the '73;<73 functioning as translation table for virtual;)hysical memory access. (n
other =ords/ (n 16bit mode, segmentation actually )erforms the role of the ##*, and
logical addresses Ffar )ointersG are virtual addresses.
*.'.1.The lassial '"bit x86 ((4
3he use of segmentation for virtual;)hysical translation may have been a))ro)riate
=hen x86 !1*s =ere 16bit only. -ut for "2bit mode, the reliance on far )ointers, or
ex)licitly segmented memory access, causes severe )roblems. Ehy should anybody
=ant to fiddle =ith multi)le segments in a))lications;o)erating systems if a single
"2bit )ointer can locate every byte of )hysical memory in a machine J
(n other =ords/ (f the segment offset alone Flo=er )arts of a logical address, no= a
"2bit valueG can address every )iece of )hysical memory in a machine, =hy bother
=ith multi)le segments Fand .8bit far )ointersG at all J Ehat>s needed for "2bit
o)eration is a flat address space % unsegmented, =ith addresses starting at Kero and
ending at .'-.
3he "2bit 1rotected #ode allo=s to create such flat segments, =hich start at Kero and
cover all of the "2bit address s)ace. -ut doing that reduces the "2bit )rotected mode
to a vehicle for supplying pri#ileges only. -y using a )air of flat segments for
a))lication code and data Frunning in ring "G, and another such flat )air for $ernel
code and data Frunning in ring 5G, both user and $ernel code can run in a flat address
s)ace.
-ut clearly doing so removes memory management from the 1egmentation ))>. 3he
descri)tor tables are no= )rogrammed in such a =ay that any memory translation
ca)abilities via descri)tor tables are bypassed. 3here>s again a 1/1 ma))ing bet=een
logical address Fi.e. far )ointerG and the result of the segmentation translation ste),
and the unit6of6memory, the segment siKe, is .'-.
(n a flat "2bit mode, a logical address cannot be translated to a )hysical address
directly. <ogical and virtual addresses are no longer e,ual, and a memory granularity
of .'- is ina))ro)riate. 2esult of the segmentation translation =ill be a virtual
address no=, and a ne= mechanism to translate this to the actual )hysical address is
re9uired.
3his means for "2bit mode, the 85"86 had to su))ly a ne= memory management unit
as a 2
nd
stage of address translation % to convert from a "2bit virtual address to a "2bit
)hysical address.
..#emory and 1rivilege #anagement on x86 1
3he "2bit ##* )erforms address loo$u)s using sim)le hashing. (n ! )seudo code, its
o)eration can be ex)ressed as/
register paddr6t EEEcr%W /E pagedir base address in cr% E/
paddr6t tables2323W
Ddefine TH:?ESU 0# CC #!1 /E #!$& E/
Ddefine PHNESU 0# CC #$1 /E &!*6 E/
Ddefine PHNEKFO6FK90'addr1 00'addr 77 $$1 \ 0TH:?ESU R #11
Ddefine PHNET:?6FK90'addr1 00'addr 77 #$1 \ 0TH:?ESU R #11
Ddefine PHNE6<@@SET0'addr1 0'addr \ 0PHNESU R #11
Ddefine AH6T<6PH0'a1 tables2PHNEKFO6FK90'a132PHNET:?6FK90'a13 ^
4 PHNE6<@@SET0'a1
(n other =ords, the virtual address is s)lit FhashedG into three )arts/
bits \"1..22] su))ly the index into the level 1 table/ 3he page directory FtableG.
Entries in the )age directory locate )age tables in )hysical memory.
bits \21..12] su))ly the index into the level 5 table/ 3he page table.
Entries in the )age table locate the actual )hysical )ages.
bits \11..5] for the offset =ithin the )hysical )age.
-oth )age directory and )age tables are s)arse arrays of Fno more thanG 152. "2bit
values. A s)ecific index can therefore locate a )hysical )age if the table contains a non6
>Q?? pagetable entry that su))lies sufficient )ermissions for the running code the
access this )age.
4ther=ise, the ##* =ill cause a pagefault FDP@ tra)G. 3his ha))ens if/
the )agetable entry is >Q??, as indicator of unma))ed memory
the )agetable entry present bit has been cleared by the o)erating system to indicate
e.g. a s=a))ed6out )age
the running code executes at ring ";5 but the user;super#isor bit in the )agetable
2 ..#emory and 1rivilege #anagement on x86
Illustration J ! classical F3bit %&' ))>
10bit
PDT index
10bit
PT index
12bit page offset
32bit
!hysical
address
PKE2!3
PKE2#3
PKE2...3
PKE2#!$%3
PKE2#!$$3
PKE2#!$#3
page directory
table
page
table
PTE2#!$%3
PTE2#!$$3
PTE2...3
PTE2#3
PTE2!3
0 31
##* context register cr%
4
20bit page frame number 12bit page offset
0 11 21 12 22 31
32bit
&irtual
address
entry indicates that this )age is su))osed to be accessible from the ?other@ mode
only.
3he DP@ tra) has its o=n pagefault address register 6 cr$. 8irtual memory Fi.e.
pagingG can easily be im)lemented via this mechanism. Ehenever a )agefault occurs,
the handler =ill find the virtual address that caused the fault in cr$. (t =ill ex)licitly
)erform the table loo$u) and ins)ect the )agetable entry at this )osition. (f the entry
doesn>t exist, it can e.g. choose to create it Fgiving semantics of MHP6H><> mmapG. (f it
exists but the )age )resent bit is clear, it may decide to e.g. load the )age from s=a).
3he illustration and the exam)les given so far already indicate that )age directory and
)age table entries are not Bust "2bit )hysical addresses. And they need not be % they
locate )ages, and because the )age siKe is a fixed .$- a 25bit number, the page frame
number, is sufficient to enumerate all .$- )ages on a machine that allo=s for .'- of
)hysical memory. 1agetable entries therefore contain the 1C& % and attributes for that
)age. 0ome of them =ere already mentioned, the page present and the user;super#isor
attributes. -ut there are more. C'm//at6pte./7 on 0olaris 15;x86 names them/
Ddefine PT6AH?FK 0!x!!#1 /E a 'alid translation is present E/
Ddefine PT6POFTH:?E 0!x!!$1 /E t/e page is Britable E/
Ddefine PT6QSEO 0!x!!&1 /E t/e page is accessible b; user mode E/
Ddefine PT6POFTETMOQ 0!x!!81 /E Brite back cac/ing is disabled 0non)PHT1 E/
Ddefine PT6><CHCME 0!x!#!1 /E page is not cac/eable 0non)PHT1 E/
Ddefine PT6OE@ 0!x!$!1 /E page Bas referenced E/
Ddefine PT6M<K 0!x!&!1 /E page Bas modified E/
Ddefine PT6PHNESFUE 0!x!8!1 /E abo'e le'el !" indicates a large page E/
Ddefine PT6PHT6&= 0!x!8!1 /E at le'el !" used for Brite combining E/
Ddefine PT6N?<:H? 0!x#!!1 /E t/e mapping is global E/
Ddefine PT6S<@TPHOE 0!xe!!1 /E a'ailable for softBare E/
3he u))er 25bits of a )agetable entry =ill of course contain the )age frame number.
13Es therefore have the follo=ing format/
As sho=n, there are no s)are;reserved attribute bits left % all are used. 3his =asn>t so
in the 85"86, =hich did not have global or large )ages nor caching attributes. 3hese
##* features, as usual =ith x86, have to be detected and activated before use, and
CPQFK is re9uired to find out =hether a given x866com)atible !1* has these features.
Ehat>s noticeably missing from the "2bit ##* is an attribute for )age executability.
?!lassical@ x86 has this in the segmentation ##* only, in form of code segments. 3his
means that in flat address s)aces, a )age is executable if it is readable A
..#emory and 1rivilege #anagement on x86 "
Illustration & ! F3bit pagetable entry
31 0 1 2 3 4 5 7 6 8 9 12
25bit )age frame number
11
for "1
usage
P
O
/
P
Q
/
S
P
T
>
C
?
P
O
E
@
M
<
K
N
*.'.".Physial #ddressing %xtension BP#%C
3en years after the introduction of the 85"86, x866based systems had evolved far
enough Fand far beyond =hat (ntel had antici)atedG that the need for big server
systems ca)able of accessing more than .'- of )hysical memory became evident.
!om)eting "2bit architectures of that time, li$e sun.d;"2bit sun.u, 1A62(0! 7xxx or
#(10 "xxx =hich =ere all used in server systems by various vendors, have had ##*s
that allo=ed the o)erating system to hold several "2bit )rograms including all of their
.'- address s)ace in system memory concurrently. 3his re9uires ##* translation
modes that convert "2bit virtual addresses into more6than6"2bit )hysical addresses.
3he "2bit x86 ##* had no )rovisions for that. 3here are no s)are;reserved bits in
"2bit )agetable entries, so the )age frame number couldn>t sim)ly be extended. (n
addition to that, the siKe of a )agetable had to be one )hysical )age F.$-G, so (ntel
neither could Bust double the siKe of )agetable entries.
(ntel therefore had to/
increase the siKe of a )agetable entry from "2bit to 6.bit, using Fsome ofG the ne=
s)are bits for a larger )age frame number
half the siKe of )age table;)age directory table from 152. entries to 512 entries so
that the total siKe of the table =ould stay .$-.
-ut halving the table siKe to 512 of course means that the virtual address can no
longer be s)lit 15/15/12 % but 2///12, necessitating/
the introduction of a third translation table.
3his so6called :age Directory :ointer +able can, given that there are only t=o bits for
its index, only contain four entries of course.
3his ##* mode, called :hysical 5ddressing (%tension F1AEG, =as introduced =ith the
1entium1ro;(( !1*s and uses three levels of translation tables/
. ..#emory and 1rivilege #anagement on x86
Illustration M ! :hysical 5ddress (%tension: allo$ '*9A memory in F3bit mode
9bit
PDT index
9bit
PT index
12bit page offset
36bit
!hysical
address
PKE2!3
PKE2#3
PKE2...3
PKE2-##3
PKE2-#!3
PKE2-!*3
page directory
table
page
table
PTE2-##3
PTE2-#!3
PTE2...3
PTE2#3
PTE2!3
0 35
##* context register cr%
4
24bit page frame number 12bit page offset
page directory
pointer table
PKE2!3
PKPTE2#3
PKPTE2$3
PKPTE2%3
0 11 20 12 21 29 31
2
b
i
t
32bit
&irtual
address
the page directory pointer table Ffour entries onlyG
the page directory table F=hich no= has 512 entriesG
the page table.
3he format of )agetable entries is t=ice the siKe as before, but uses the same format
including all of the attribute bits =ith t=o exce)tions/
1. 3he )age frame number is no= Fat leastG 2.bits.
2. (f the !1* su))orts it, bit 6" is a ne= )age attribute ?&+@ 6 not e%ecutable.
3he &+ bit got introduced by A#7 in the 4)teron )rocessors, but it>s not 6.bit
s)ecific. As usual =ith x86 extensions, the )resence of the &+ bit can be 9ueried by
the o)erating system using the CPQFK instruction.
!1*s that have the &+ bit the long6missing ca)ability in F"2bitG x86 to )rotect areas of
memory from being executed. 3he feature is also called Data (%ecution :rotection
F7E1G by #icrosoft, and (nhanced Virus :rotection FE81G by A#7 #ar$eting % though
the latter is a technically a misleading term, since the ?only@ thing &+ )rotects against
are sim)le6=ritten stac$ overflo= ex)loits.
..#emory and 1rivilege #anagement on x86 5
Illustration L ! '*bit pagetable entry. F'bit :5( mode
36 0 1 2 3 4 5 7 6 8 9 12
2.bit )age frame number
11
for OS
usage
63
O
/
P
P
Q
/
S
P
T
>
C
O
E
@
M
<
K
?
P
N
>
9
bits 37..62 reserved (shall be 0)
*.'.'.The #()6* 6*bit ((4
3he maBor reason for going to 6.bit, =hatever !1* vendor, has al=ays been to allo=
concurrent access to large virtual address s)aces. 3his of course mandated a ne=
##* mode % both the classical "2bit x86 ##* and the 1AE mode are only su))orting
"2bit virtual addresses.
A#7 in designing the 6.bit mode retained all existing x86 characteristics. (t>s
therefore not sur)rising that the 6.bit ##* mode is sim)ly an extension of 1AE mode
to 6.bit virtual addresses. 1AE mode )ro)erties also found in the 6.bit ##* are/
)ages are 2
12
bytes, .$-.
1age directory entries can )oint to large )ages of 2
21
bytes, 2#-.
)agetable entries use the 1AE format F6.bit =ide, attribute bits identical to 1AEG
translation tables contain 2

F512G entries.
3he big deficit of 1AE mode, unbalanced translation tables because of the use of only
2 bits for the )age directory )ointer table index, of course is solved because 6.bit
virtual addresses su))ly enough bits to ma$e that table, li$e all others, 512 entries.
A#7 additionally added a fourth table, sim)ly called ?:age )ap ?e#el *@. 3he 6.bit
##* therefore loo$s li$e this/
1agetable entries, as mentioned, use the 1AE format % exce)t, of course, the 1C&
=hich is no longer 2.bit as in "2bit 1AE mode, but .5bit no=.
3his allo=s the 6.bit ##* to access 2
52
bytes of memory, .1- in total.
3he 6.bit ##* of course su))lies the &+ bit that A#7 introduced =ith the 4)teron
and Athlon6. !1* series. 6.bit )agetable entries use the follo=ing format/
6 ..#emory and 1rivilege #anagement on x86
Illustration ! '*bit %&' ))>
PTE2-##3
PTE2-#!3
PTE2...3
PTE2#3
PTE2!3
4
Mbit
:D+ inde%
52bit
!hysical
address
PKE2!3
PKE2#3
PKE2...3
PKE2-##3
PKE2-#!3
PKE2-!*3
page directory
table
0 51
##* context register cr%
3bit page offset
page directory
pointer table
PKE2!3
PKPTE2#3
PKPTE2$3
PKPTE2-##3
PKPTE2...3
PM?&E2!3
PM?&E2-#!3
PM?&E2-##3
PM?&E2...3
page map
level7
Mbit
:D:+ inde%
Mbit
:)?* inde%
6#bit &irtual address
'bit canonical part
0 20 21 29 30 38 39 47 48 63
page frame number
12 11
Mbit
:+ inde%
3bit page offset
page table
Ehat needs ex)lanation of course is the 9uestion =hat the virtual address bits that are
not used for )age offset and table indices are su))osed to be. 0im)le arithmetics tells
us that the ##* uses 12DDDD X .8 bit for address translation only. Ehat>s the
state of the u))er 16 bits of a virtual address J
3he ans=er to that is that the ##* =ill only )erform address translation if the u))er
16bits are either all 8ero or all one, de)ending on the state of bit *J.
(f =e consider the 6.bit virtual address s)ace to be unsigned and to extend from 5 to
2
6.
61, this s)lits the addressable virtual memory into t$o ranges of 2
.7
bytes F1283-G
each, one at the bottom and one at the top of the virtual address s)ace/
3he u))er and lo=er address s)aces are se)arated by an address space hole.
3ranslateable virtual addresses that match the condition of bits 6"...7 inclusively are
either all Kero or all one, i.e. that the address is either =ithin the lo= 1283- or the
high 1283- of the virtual address s)ace, are called canonical addresses. 8irtual
addresses in the hole are noncanonical and their use causes DNP faults.
8irtual address s)aces =ith holes are not ne= in 6.bit environments. Cor exam)le,
*ltra01A2!6( and (( also had an address s)ace hole Fbut they =ere even more limited
than A#76. % =ith only 2x13- of virtual address s)aceG.
3here is a different =ay of understanding 6.bit ##*s =hich use a canonical mode.
!onsider the virtual address to be a signed *&bit #alue. (.e. virtual addresses range
..#emory and 1rivilege #anagement on x86 7
Illustration F ! 5ddress space hole in 5)D'*
6#bit &irtual address
16bit canonical part
47 48 63
1111111111111111 1 11111111111111111111111111111111111111111111111
1111111111111111 1 000000000000000000000000000000000000000000000000
0000000000000000 0 11111111111111111111111111111111111111111111111
0000000000000000 0 000000000000000000000000000000000000000000000000
Address Space <ole
non6translatable virtual addresses
memory access in this range causes DNP faults
46 0
(
128 3- upper virtual address s)ace
!xffffffffffffffff...!x8!!!!!!!!!!!
128 3- lo$er virtual address s)ace
!x!...!x.fffffffffff
Illustration 3 ! '*bit pagetable entry. '*bit mode
52 0 1 2 3 4 5 7 6 8 9 12
.5bit )age frame number
11
for OS
usage
63
O
/
P
P
Q
/
S
P
T
>
C
O
E
@
M
<
K
?
P
N
>
9bits BF..'3 reser#ed
Dshall be LE
from 62
.7
...2
.7
61 bytes Fi.e. 1283-G. 3he u))er bits of the 6.bit address are therefore
derived by sign e%tension.
(n this signed re)resentation, there is no address s)ace hole. Allo=ed virtual addresses
are continuous over a 2563- range, =hile virtual addresses outside of that range are
undefined and cause DNP faults =hen used.
3he terms negati#e address range and upper address range describe the same thing,
and are often used interchangeably.
8 ..#emory and 1rivilege #anagement on x86
Illustration * ! signed #irtual addresses
6#bit &irtual address
47 48 63
)))))))))))))))) ) 11111111111111111111111111111111111111111111111
)))))))))))))))) ) 00000000000000000000000000000000000000000000000
++++++++++++++++ + 11111111111111111111111111111111111111111111111
++++++++++++++++ + 00000000000000000000000000000000000000000000000
128 3- negati#e virtual address s)ace/
)!x!!!!!!!!!!!#...)!x8!!!!!!!!!!!
128 3- positi#e virtual address s)ace
!x!!!!!!!!!!!!...!x.fffffffffff
non!translatable #irtual addresses I access causes #GP faults
46 0
*
non!translatable #irtual addresses I access causes #GP faults
16bit canonical part
*.'.*./arge Pages
Cor accessing very large amounts of memory, .$- )ages are inconvenient and slo= for
obvious reasons/
Having the o)erating system create e.g. 1 million )agetable entries to allocate a
.'- chun$ of memory ta$es a =hile.
!ached translations F3<-;translation lookaside buffer entriesG =ill sho= heavy
contention =hen so many translations need to be done all the time.
(n order to s)eed u) the use of large amounts of memory, large pages are being used.
3he common mechanism for creating a large )age is to use a higher6level translation
table entry as ?large :+(@ and ma$e the siKe of large )ages the sum of the siKes of all
)ages in the next lo=er6level table. (n x86 terms, a )age directory entry that has the
largepage attribute bit set =ill not )oint to a )agetable, but directly to the )hysical
location of the large )age. 0ince )agetables contain 512 entries, the siKe of a large
)age =ill be 512x.$-, 2#- Fif using the classical "2bit ##* mode/ 152.x.$-, .#-G.
3he ca)ability to su))ort large )ages, as all of the )ost685"86 features, again must be
detected using a !1*(7 instruction, and selectively enabled. All 6.bit6ca)able x86
!1*s su))ort large )ages, but not necessarily all "2bit ?x86 com)atibles@.
At this time, there is no su))ort for V2#- large )ages Fthe next logical siKe =ould be
512x2#-, 1'-G in the x86 ##*. (t>s li$ely, though, that if this is ever introduced that
it>ll be done the same =ay % by ma$ing a )age directory )ointer table entry refer to a
?huge page@ of 1'- then, or even a ?giant page@ of 512'-, if ever the )age ma) level
. table may )oint directly to a )age...
(n any case, turning around the conce)t of large )ages/
A >Q?? as table entry means/
..#emory and 1rivilege #anagement on x86
Illustration B ! using large pages
Mbit
:D+ inde%
3bit page offset
52bit
!hysical
address
PKE2!3
PKE2#3
PKE2...3
PKE2-##3
PKE2-#!3
PKE2-!*3
page directory
table
0 51
##* context register cr%
4
3bit page
offset
page directory
pointer table
PKE2!3
PKPTE2#3
PKPTE2$3
PKPTE2-##3
PKPTE2...3
PM?&E2!3
PM?&E2-#!3
PM?&E2-##3
PM?&E2...3
page map
level7
Mbit
:D:+ inde%
Mbit
:)?* inde%
6#bit &irtual address
'bit canonical part
0 20 21 29 30 38 39 47 48 63
page frame number
an unma))ed area of 512'- if in the 1#<. table
an unma))ed area of 1'- if in a )age directory )ointer table
an unma))ed area of 2#- if in a )age directory table
an unma))ed )age of .$- if in a )age table.
155 ..#emory and 1rivilege #anagement on x86
*.*.#d&aned System Programming TehniD!es on
x86
*.*.1.)(# !sing &irt!al addresses - $O((4
*.*.".4sing the Proteted (ode for Hardware
2irt!aliEation
#odern system architectures often allo= to run multi)le o)erating system instances
on the same )hysical machine. 7omaining ; hard=are )artitioning ; virtualiKation are
the terms used to describe this ca)ability. 0u))orting this re9uires
..#emory and 1rivilege #anagement on x86 151
8.$nterr!pt handling1 )e&ie
#!toonfig!ration
8.1.$nterr!pt Handling and $nterr!pt Priority
(anagement
x86 )rocessors alone $no= only interru)t vectors Findices into the (73G and a bit in the
)rocessor status register E@?HNS;O@?HNS that says ?interru)ts enabled@. 3he !1*
$no=s no conce)t of interru)t )riorities. 3o a x86 !1*, all 255 Fres). all user6available
22"G interru)t vectors are e9ual. 3he )rocessor has )ins that connected )eri)heral
devices can use to ?cause interru)ts@, but a)art from ?ignore all@ F(E bit clear % after a
cli instructionG and ?acce)t all@ FFE bit set, after a sti instructionG it hasn>t the ability
to selectively bloc$ interru)ts, e.g. from a lo=6)rio dis$ device if a handler for a high6
)rio net=or$ interru)t is Bust running. All of the follo=ing/
-inding hard=are interru)t sources to !1* interru)t vectors,
classifying interru)ts on )eri)heral devices into different )riority classes, and
selectively bloc$ing out s)ecific devices or s)ecific interru)t )riorities
manage interru)t state Finterru)t active;)endingG
has, on x86 )latforms, al=ays been the tas$ of a device called :rogrammable Interrupt
0ontroller F1(!G. 3he ?classical@ x86 1(! is the (ntel i825A.
5.(nterru)t handling, 7evice Autoconfiguration 15"
8.".#P$C and $O#P$C feat!res
8.".1.O&er&iew
(n a multi)rocessor environment, interru)t handling becomes significantly more
com)licated than before. 3he interru)t controller in 0#1 systems must )rovide all the
ca)abilities of interru)t management and )rioritiKation as the sim)le 1(!, but in
addition to that, a 0#16ca)able interru)t controller must be able to/
route interrupts. (t>s highly undesirable on a multi)rocessor system to bother all
!1*s at once =ith handling a s)ecific device interru)t.
support inter!processor interrupts, i.e. a !1* itself being the interru)t source of
another !1*.
Eith the introduction of the 1entium F15G micro)rocessor architecture, (ntel
integrated 0#1 su))ort on chi), =ith an interru)t arbitrator ; coherency controller
subsystem called the 5d#anced :rogrammable Interrupt 0ontroller, A1(!.
Every modern x86 )rocessor contains a local 5:I0, =hose tas$s are/
2eceive and dis)atch local interru)ts Ffrom devices directly connected to !1*
interru)t )insG
7is)atch !1*6internal interru)ts FA1(! timer, tem)erature sensors, )erformance
monitoring eventsG
2eceive and dis)atch external interru)ts Ffrom the (4A1(!, a system;)eri)heral bus
com)onent that routes )eri)heral interru)ts via the A1(! )rotocolsG
2eceive and dis)atch inter6)rocessor interru)ts, (1(s F(A"2 term for crosscallG.
15. 5.(nterru)t handling, 7evice Autoconfiguration
Illustration ! 5:I0 functionality
A*I, A System bus
*eripheral bus
d
e
v
i
c
e
d
e
v
i
c
e
d
e
v
i
c
e
d
e
v
i
c
e
d
e
v
i
c
e
I0A%I-
-%1 *
local
A1(!
!"#i$ter$al
i$terru%t sour&es
-%1 1
local
A1(!
!"#i$ter$al
i$terru%t sour&es
-%1 3
local
A1(!
!"#i$ter$al
i$terru%t sour&es
-%1 2
local
A1(!
!"#i$ter$al
i$terru%t sour&es
directed crosscall
broadcast
crosscall
de#ice interrupt
#anage interru)t )riorities.
3he chi)set =ill contain an external or (;4 A1(!, =hich is then used as a
)rogrammable dis)atch facility for hard=are interru)ts to the various local A1(!s of
the )rocessors in the system.
3he A1(! routes external F(4A1(!G and local Fsee aboveG interru)t sources to (A"2
interru)t numbers in a user6)rogrammable =ay. A1(! registers used for this )ur)ose
contain the (A"2 int[ to dis)atch on event in their lo=est 8 bits.
3he A1(! grou)s interru)t vector numbers F5..255G into 16 )riority grou)s, =ith the
)riority of an interru)t given by int[;16. 1riority 5 and 1 are highest Fhard=are
exce)tionsG, and can neither be created nor bloc$ed by the A1(!. 1riorities 2..15 are
available to A1(! interru)ts. 3he +ask :riority 2egister, TPO, allo=s to bloc$ interru)ts
of lo= )riority, =hile the read6only :rocessor :riority 2egister, PPO, reflects the
current settings.
!1*6!1* communication is executed via Inter!:rocessor Interrupt, (1(, the x86 term
for LcrosscallL. 3o generate (1(s, the (nterru)t !ontrol 2egister, (!2, is =ritten. 3he
(!2 alone enables the )rogrammer to/
dis)atch a )rogrammable int[ to a single other !1* Ftargeted (1(G
broadcast a )rogrammable int[ to all !1*s, including;excluding the sending !1*
Additional A1(! registers, the ?ocal Destination 2egister, ?KO, and the Destination
Format 2egister, K@O, allo= even for multicast (1(s Frestricting broadcasts to a
selected set of !1*sG.
3he A1(! is )rogrammed li$e a memory6ma))ed deviceN base address for the ma))ing
is the machine6s)ecific FH%$6HPFC6:HSE register, any A1(! registers are offset
relatively to the base. 3o read or =rite an A1(! register, sim)ly access memory at the
corres)onding offset relative to the A1(! base address.
3he (4A1(! is a ?doubly indirect@ ma))ed device. (t has t=o registers FF<OENSE? and
F<PF>G that are accessed relative to the 1outhbridge>s HPFC6:HSE. Fthis is not the same
as the !1*s FH%$6HPFC6:HSE AG (4E(& ma)s to one of the actual (4A1(! registers
de)ending on the value in F<OENSE?. (.e. to )rogram an (4A1(! register, the register
number is )ut into F<OENSE? first, and the actual (4A1(! register is then accessed via
F<PF>.
8.".".#P$C interr!pt registers
A1(! registers, =hether (4A1(! F(ntel 825"AAG or !1*6local A1(!, use a common
format for all registers associated =ith interru)t delivery/
3he bits have the follo=ing meaning/
5..7/ F>TD
the x86 interru)t vector to dis)atch to the target !1*FsG on event
8..11, delivery mode ; destination mode Fonly in registers for nonlocal deliveryG
decides =hich !1*s are targeted in broadcast;multicast routing modes
12/ 70 Fdelivery statusG
indicates =hether an interru)t of this ty)e is )ending F9ueuedG due to higher6
5.(nterru)t handling, 7evice Autoconfiguration 155
Illustration 3 ! 5:I0 2egister format. for interrupt!dispatch related registers
' 3 J L
F>TD
D)
D1+ )
D
1
)
1
Q
'
)rioritiKed interru)t handlers running
16/ #0: Fmas$G
can be used to selectively bloc$ generation of interru)ts from interru)t sources
FdevicesG controlled by the given F(4GA1(! register.
56..6"/ destination A1(! (7 Fonly in registers for non6local delivery, i.e. the (4A1(!
redirection table and the local A1(!>s (nterru)t !ommand 2egisterG determines the
interru)t target !1* set, together =ith the delivery ; destination mode bits and t=o
A1(! control registers Flogical destination register, destination format registerG.
3he main A1(! registers related to interru)t creation;dis)atch are on 1entium6(8
systems Fothers may not have all of the 16(8>s ?AT23 registers % again, as$ via CPQFKG/
A*I, base
B...
+egister Description
!x%$! ?AT2!3 timer register.
1rogram high6resolution timer interru)ts here.
!x%8!/*!
!x%e!
CCO, FCO, KCO current count;initial count;di#ide configuration register.
Additional state for the A1(! timer.
!x%%! ?AT2#3 thermal monitor register.
!reate interru)ts on danger of overheating.
!x%&! ?AT2$3 performance counter register.
(nterru)ts for )rofiling.
!x%-!
!x%6!
?AT2%3
?AT2&3
local de#ice L register
local de#ice register
!x%.! ?AT2-3 5:I0 error register.
!reate interru)t if A1(! encounters an error.
!x$8! ESO (rror status register.
Auxilliary FreadonlyG information on A1(! errors.
!x%!!
!x%#!
FCO Interrupt 0ommand 2egister F6.bitG
!reate inter6)rocessor interru)ts.
!xd!
!xe!
?KO, K@O ?ogical Destination ; Destination Format 2egister.
*sed to clarify destination !1*s for (1(s.
3he (4A1(! uses a set of 2. registers called I/" 2edirection +able that uses the
mentioned format to dis)atch events on the )eri)heral bus via the A1(! mechanism.
3he F<OEKFO23 registers use the described generic register format to select interru)t
vector and target !1*.
156 5.(nterru)t handling, 7evice Autoconfiguration
8.".'.$nterr!pt priorities1 cr8
3he A1(! Fas =ell as the older i8257 1(!G uses a sim)le ma))ing bet=een interru)t
)riorities and x86 interru)t vectors/
(nterru)t 1riority / vector[ ; 16
1riority subclass / vector[ Y 16
(.e. high6)riority interru)ts get high interru)t vector numbers.
3his ma))ing is not configurableN =hat the A1(! allo=s to do is to bloc$;9ueue
interru)ts not only based on the interru)t source T #0: bit, but also based on
)riority. Cor that )ur)ose, the A1(! )rovides a ?)riority register@ =hich comes in t=o
flavours/
+egister ?ame Description
+ask :riority 2egister,
TPO
Erite6only register. 4ffset !x8!
*sed to set the current (1< F(nterru)t 1rivilege <evelG.
:rocessor :riority 2egister,
PPO
2ead6only register. 4ffset !xa!
*sed to 9uery the current (1<.
2ecent x86 !1*s ma) the A1(! (nterru)t 1riority register directly to a ne= !1*
control register. cr8, if available, serves both )ur)oses, to 9uery and set the current
(1<.
5.(nterru)t handling, 7evice Autoconfiguration 157
8.".*.#P$C interr!pt proessing flow
3he A1(! runs concurrently =ith and asynchronously to the !1*, in a state machine
similar to the follo=ing/
3hree additional A1(! registers are involved =ith this flo=/
Interrupt 2e,uest 2egister, FOO.
3he FOO is a 256bit6=ide bitma) % a )ending but not6yet6dis)atched interru)t =ill
result in a bit being set in the FOO.
3he A1(! )ermanently monitors Factive, i.e. not mas$edG interru)t sources and
automatically manages the bitma) in FOO.
3he register occu)ies 256bit of memory, offsets !x$!!..!x$.! to the base. 0oft=are
can read this for debug )ur)oses Fbut not =rite itG.
In!1er#ice 2egister, FSO.
3he A1(! uses FSO to indicate =hich interru)t is currently being serviced by the
!1*. 3he FSO contains the vector number. (t>s again a 256bit6=ide register, but
unli$e the FOO it can only contain exactly one bit set. 3he A1(! automatically
moves the highest6)riority bit from FOO to FSO and dis)atches the interru)t vector
to the !1* if FSO gets cleared.
Again, 256bit of memory at offsets !x#!!..!x#.! ma) the FSO. (t>s also readonly.
(nd!of!Interrupt 2egister, E<F.
3his register is =riteonly and used as a trigger. 3he interru)t service routine
running on the !1* =rites to E<F to indicate com)letion. Eriting E<F clears FSO
and causes the A1(! to continue interru)t dis)atch if there are interru)ts 9ueued
via FOO. 3he value =ritten to E<F is irrelevant % as said, it>s a )ure trigger.
158 5.(nterru)t handling, 7evice Autoconfiguration
Illustration F ! 5:I0 interrupt processing $orkflo$
interru)t handler runs,
=rites E<F at end
A1(! moves F>TD bit from FOO
to active F>TD bit in FSO
A1(! clears active
F>TD bit in FSO
2I+/
set, handler
running
J
int
)ending
J
FOO
indicates
interru)t
J
!1* dis)atches F>TD
handler via gate in (73
A1(! sets re9uested
$.TF bit in %IRR
no
yes
yes
no
yes
A1(! dis)atches F>TD to !1*
CP4
5.(nterru)t handling, 7evice Autoconfiguration 15
6.Solaris=x86 arhitet!re
Crom ?3he 3ao of 1rogramming@/
+he $arlord asked the programmer:
NHhich is easier to design: an accounting package or an operating systemGN
N5n operating system.N replied the programmer.
+he $arlord uttered an e%clamation of disbelief.
N1urely an accounting package is tri#ial ne%t to the comple%ity of an
operating system.N he said.
N@ot so.N said the programmer. N$hen designing an accounting package. the
programmer operates as a mediator bet$een people ha#ing different ideas:
ho$ it must operate. ho$ its reports must appear.
and ho$ it must conform to the ta% la$s.
Ay contrast. an operating system is not limited by outside appearances.
Hhen designing an operating system.
the programmer seeks the simplest harmony bet$een machine and ideas.
+his is $hy an operating system is easier to design.N
+he $arlord of Hu nodded and smiled.
N+hat is all good and $ell. but $hich is easier to debugGN
+he programmer made no reply.
3o be covered here/
0olaris (nternals
6.0olaris;x86 architecture 111
6.1.3ernel and !ser mode
3he =ay ho= 0olaris;x86 sets u) the 6.bit )rotected mode is subBect to the follo=ing
constraints/
3he use of a bootloader and the use of -(40 services re9uires thun$ing interfaces
bet=een the F6.bitG $ernel and the 6.;"2bit )arts of the bootloader that su))ly the
booto)s services. 3his is =hy the descri)tor table contains a set of )rivileged
code;data descri)tors for calling into bootloader;-(40 during system startu).
*sing fast system call mechanisms Fs;scall and;or s;senterG mandates the sho=n
ordering of code;data segments Fi.e. the $ernel data segment must directly follo=
the $ernel code segment in the descri)tor table, because this assum)tion is im)licit
in the =ay fast syscalls are set u)G.

112 6.0olaris;x86 architecture


Illustration ! 1olaris L/%&' '*bit protected mode
@>?? Descriptor
DF3bit data. bootE
DF3bit code. bootE
D'*bit data. bootE
D'*bit code. bootE
'*bit kernel code
'*bit kernel data
F3bit user code
user data
'*bit user code
'*bit ?D+ descriptor
'*bit +11 descriptor
user gs
user fs
! !x!
# !x8
$ !x#!
% !x#8
& !x$!
- !x$8
6 !x%!
. !x%b
8 !x&%
* !x&b
#! !x-%
#$ !x6!
-- !x#bb
-6 !x#c%
seg# selector
si8e: 6ma%7
5ll address spaces are
implicitly flat
base address: >Q??
...
F3bit compatibility syscall & !x$.
segD selector
>Q?? Descriptor
>Q?? Descriptor
userA9ernel
virtual address space
+olaris 3)4
Default /D.
segment
not present !
6.".%ntering the Solaris=x86 ,ernel
#any hard=are6 and soft=are6initiated events in 0olaris re9uire handling by the
$ernel. 3he follo=ing events enter the $ernel via gates in the (73/
All x86 interru)ts, =hether created by hard=are Fvia A1(! and;or (4A1(!G or via an
ex)licit int ... instruction, call a handler in the $ernel.
All x86 hard=are tra)s are redirected to the $ernel.
7ebugging utilities Fmdb;$mdb and other debuggers as =ell as 73raceG use
ex)licitly tra))ing instructions Fud$, int ...G to control other )rograms.
<egacy Fclassical "2bitG system calls use the lcall ,!x$."! instruction to call a
gate in the <73.
3his re9uires using a call gate =hich has disadvantages/ call gates don>t save @?HNS,
and neither can they disable interru)ts before dis)atch. (nterru)t gates do both, but
they must be in the (73.
(n order to use an interru)t gate, the follo=ing tric$ is used/ 3he ?segment )resent@
attribute in the <73>s syscall gate is cleared. 4n the attem)t to call that gate, a D>P
tra) is raised and the legacy syscall is ?doubly redirected@ to the D>P tra) handler
from the (73.
3he early ado)ter version of the <inux A))lication Environment F?Ranus@G for 0olaris
)rovides a handler for classical <inux syscalls, =hich are done using the int ,8!
instruction.
0olaris 15 uses fast system calls if the !1* model it>s running on )rovides them. 3he
fast system call mechanisms don>t re9uire gate descri)tors. (nstead, $ernel cs;ss
and rsp;rip F$ernel stac$ )ointer and system call handler addressG are )rogrammed
using the machine6s)ecific registers described in section ".2.".
3he follo=ing system call mechanisms are su))orted/
"2bit com)atibility;legacy system calls via lcall ,!x$."!.
3he 6.bit $ernel is redirects this to D>P by clearing the seg )resent bit.
6.0olaris;x86 architecture 11"
Illustration 3 ! (ntering the 1olaris/L kernel on %&' platforms
Solaris 10/x86
32bit/64bit
kernel
legacy "2bit syscalls
lcall ,!x$."!
"2bit A#7 syscalls
6.bit syscalls
s;scall/s;sret
"2bit (ntel syscalls
s;senter/s;sexit
<inux syscalls
int ,8!
fast com)atibility syscalls
int ,!x*#
$mdb
73race )rovider
x86 HE tra)s
Interrupts
(i'%li&it via ()*)
HW Interrupts
Timers
Crosscas
Traps!"#ceptions
(i'%li&it via ()*)
instructions (e#picit)
$ard%are events (impicit)
"2bit system calls via s;scall instruction Fon A#7 !1*s that su))ort itG
"2bit system calls via s;senter instruction Fon (ntel !1*s that su))ort itG
6.bit system call via s;scall instruction Fall 6.bit x86 !1*s have s;scallG
0olaris ;x86 and belo= do not use fast system calls.
3he (nterru)t 7escri)tor 3able on 0olaris 15;x86 contains the follo=ing entries in
6.bit mode/
ec/o Iidt!"!t$-6/an#64I G mdb )k G sed )e ]s/:/::gate6desc/g] G
mdb $& G naBk ],#[[IMH>K?EOI \\ f[[# VnextX ,#[[IMH>K?EOI Vf[#X VprintX]
MH>K?EO SE? KP? P TSP FST
di'!trap $8 ! 4 int !
dbgtrap $8 ! 4 int !
nmiint $8 ! 4 int !
brktrap $8 % 4 int !
o'flotrap $8 % 4 int !
boundstrap $8 ! 4 int !
in'optrap $8 ! 4 int !
ndptrap $8 ! 4 int !
s;serrtrap $8 ! 4 int #
res'trap $8 ! 4 int !
in'tsstrap $8 ! 4 int !
segnptrap $8 ! 4 int !
stktrap $8 ! 4 int !
gptrap $8 ! 4 int !
pftrap $8 ! 4 int !
res'trap $8 ! 4 int !
ndperr $8 ! 4 int !
ac/ktrap $8 ! 4 int !
mcetrap $8 ! 4 int !
xmtrap $8 ! 4 int !
in'altrap $8 ! 4 int !
2 ... 3
in'altrap $8 ! 4 int !
i'ct%$ $8 ! 4 int !
2 ... 3
i'ct#$- $8 ! 4 int !
dtrace6fasttrap $8 % 4 int !
dtrace6ret $8 % 4 int !
i'ct#$8 $8 ! 4 int !
2 ... 3
i'ct$!* $8 ! 4 int !
fasttrap $8 % 4 int !
i'ct$## $8 ! 4 int !
2 ... 3
i'ct$-- $8 ! 4 int !
As can be seen, all of these gates have the )resent bit set F?4@G. Ehich as mentioned
the <73 com)atibility system call gate has not/
7 ldt!6default4!x$!::gate6desc
MH>K?EO SE? KP? P TSP FST
s;s6lcall%$ $8 % c #
3his means the com)atibility syscall =ill cause a [&1 tra) and enter the $ernel via
segnptrap01. 0o the stub s;s6lcall%$ can never be enteredN if it yet =ould ha))en/
7 s;s6lcall%$::dis
s;s6lcall%$: pus/+ ,!x!
s;s6lcall%$4$: pus/+ rbp
s;s6lcall%$4%: mo'+ rsp"rbp
11. 6.0olaris;x86 architecture
H
a
r
d
w
a
r
e

E
x
c
e
p
t
i
o
n
s
/
T
r
a
p
s
reserved vectors
P
r
o
g
r
a
m
m
a
b
l
e
I
n
t
e
r
r
u
p
t
s
s;s6lcall%$46: lea+ !x.0rip1"rdi
s;s6lcall%$4!xd: xorl eax"eax
s;s6lcall%$4!xf: call 4!x&!ff# Cpanic7
7 s;s6lcall%$4!xd4./S
!xfffffffffb8!#8e&: s;s6lcall%$: s/ouldn]t be /ereJ
All other hard=are exce)tions have a similar structure/
!1* dis)atches the gate handler
the gate handler may or may not do lo=6level =or$N in the end, it )ushes a s)oofed
error code Fif the gate itself didn>t create a real oneG and the exce)tion number to
the stac$ and calls cmntrap01.
An exam)le/
7 pftrap::dis
pftrap: pus/+ ,!xe
pftrap4$: Tmp )!x$b#b$ C6cmntrap7
7 di'!trap::dis
di'!trap: pus/+ ,!x!
di'!trap4$: pus/+ ,!x!
di'!trap4&: Tmp )!x$a.c& C6cmntrap7
3he DP@ tra) entry has already been called =ith an error code on the stac$, =hile the
!1* doesn>t )ush one for DKFA tra)s. 3his ma$es sure that the common tra) handler
starts =ith the same stac$ layout no matter ho= it is entered/
!xfffffe8!!!.&bfb8: !xb trap number
!xfffffe8!!!.&bfc!: !x$& error code Dmay be spoofedE
!xfffffe8!!!.&bfc8: !xbff!ff8c ripAeip that caught the trap
!xfffffe8!!!.&bfd!: !x%b cs at time of trap
!xfffffe8!!!.&bfd8: !x#!$!$ O@?HNSAE@?HNS before trap
!xfffffe8!!!.&bfe!: !x8!&.b*c rspAesp at time of trap
!xfffffe8!!!.&bfe8: !x&% ss at time of trap
3he bottom t=o values, as is the behaviour of gates on x86, are only )resent if/
3he !1* =as o)erating in 6.bit mode
3he !1* =as o)erating in "2bit mode and the tra) occurred =hile in usermode.
2emember, on "2bit x86 tra)s and interru)ts =hich occurred =hen the !1* already
=as running in $ernel do not record the $ernel ss;esp % their values are im)licitly
$no=n and the !1* ?o)timiKes@ gate dis)atch by not recording these values.
0ection 6." gives details =hat this means.
(nterru)ts Fvectors "2..255G do something very similar/
7 i'ct%$::dis
i'ct%$: pus/+ ,!x!
i'ct%$4$: pus/+ ,!x!
i'ct%$4&: Tmp )!x$a6$& C6interrupt7
7 i'ct%%::dis
i'ct%%: pus/+ ,!x!
i'ct%%4$: pus/+ ,!x#
i'ct%%4&: Tmp )!x$a6%& C6interrupt7
7 i'ct$--::dis
i'ct$--: pus/+ ,!x!
i'ct$--4$: pus/+ ,!xdf
i'ct$--4.: Tmp )!x$b&#. C6interrupt7
=hich means that the same ?in)ut@ stac$ layout is used for both 6cmntrap01 and
6interrupt01., exce)t that an interru)t number Fstarting at 5, ending at 5xdf X 2""G
re)laces the tra) number.
6.0olaris;x86 architecture 115
3he reason for this behaviour is that the 0olaris $ernel creates a common trapframe
format for all )ossible =ays to enter the $ernel.
!om)are the 6.bit code for 6cmntrap01 and 6interrupt01/
entering 9ernel via _cmntrap() entering 9ernel via _interrupt()
6cmntrap: sub+ ,!xa8"rsp
6cmntrap4.: mo'+ r#-"!x.!0rsp1
6cmntrap4!xc: mo'+ r#&"!x680rsp1
6cmntrap4!x##: mo'+ r#%"!x6!0rsp1
6cmntrap4!x#6: mo'+ r#$"!x-80rsp1
6cmntrap4!x#b: mo'+ r##"!x-!0rsp1
6cmntrap4!x$!: mo'+ r#!"!x&80rsp1
6cmntrap4!x$-: mo'+ rbp"!x&!0rsp1
6cmntrap4!x$a: mo'+ rbx"!x%80rsp1
6cmntrap4!x$f: mo'+ rax"!x%!0rsp1
6cmntrap4!x%&: mo'+ r*"!x$80rsp1
6cmntrap4!x%*: mo'+ r8"!x$!0rsp1
6cmntrap4!x%e: mo'+ rcx"!x#80rsp1
6cmntrap4!x&%: mo'+ rdx"!x#!0rsp1
6cmntrap4!x&8: mo'+ rsi"!x80rsp1
6cmntrap4!x&d: mo'+ rdi"!x!0rsp1
6cmntrap4!x-$: xorl ecx"ecx
6cmntrap4!x-&: mo'B gs"cx
6cmntrap4!x-.: mo'+ rcx"!xa!0rsp1
6cmntrap4!x-f: mo'B fs"cx
6cmntrap4!x6$: mo'+ rcx"!x*80rsp1
6cmntrap4!x6a: mo'B es"cx
6cmntrap4!x6d: mo'+ rcx"!x*!0rsp1
6cmntrap4!x.-: mo'B ds"cx
6cmntrap4!x.8: mo'+ rcx"!x880rsp1
2 ... 3
6cmntrap4!xa&: cmpB ,!x$8"!xc!0rsp1
6cmntrap4!xad: Te C6cmntrap4!xb$7
6cmntrap4!xaf: sBapgs
2 ... 3
6cmntrap4!xd$: mo'+ rsp"rbp
6interrupt: sub+ ,!xa8"rsp
6interrupt4.: mo'+ r#-"!x.!0rsp1
6interrupt4!xc: mo'+ r#&"!x680rsp1
6interrupt4!x##: mo'+ r#%"!x6!0rsp1
6interrupt4!x#6: mo'+ r#$"!x-80rsp1
6interrupt4!x#b: mo'+ r##"!x-!0rsp1
6interrupt4!x$!: mo'+ r#!"!x&80rsp1
6interrupt4!x$-: mo'+ rbp"!x&!0rsp1
6interrupt4!x$a: mo'+ rbx"!x%80rsp1
6interrupt4!x$f: mo'+ rax"!x%!0rsp1
6interrupt4!x%&: mo'+ r*"!x$80rsp1
6interrupt4!x%*: mo'+ r8"!x$!0rsp1
6interrupt4!x%e: mo'+ rcx"!x#80rsp1
6interrupt4!x&%: mo'+ rdx"!x#!0rsp1
6interrupt4!x&8: mo'+ rsi"!x80rsp1
6interrupt4!x&d: mo'+ rdi"!x!0rsp1
6interrupt4!x-$: xorl ecx"ecx
6interrupt4!x-&: mo'B gs"cx
6interrupt4!x-.: mo'+ rcx"!xa!0rsp1
6interrupt4!x-f: mo'B fs"cx
6interrupt4!x6$: mo'+ rcx"!x*80rsp1
6interrupt4!x6a: mo'B es"cx
6interrupt4!x6d: mo'+ rcx"!x*!0rsp1
6interrupt4!x.-: mo'B ds"cx
6interrupt4!x.8: mo'+ rcx"!x880rsp1
2 ... 3
6interrupt4!xa&: cmpB ,!x$8"!xc!0rsp1
6interrupt4!xad: Te C6interrupt4!xb$7
6interrupt4!xaf: sBapgs
2 ... 3
6interrupt4!xb-: mo'+ rsp"rbp
3his is of course common codeN on entry, the se9uence of instructions does/
=rite the general6)ur)ose registers to the stac$
)ut segment registers ds;es;fs;gs on the stac$ Fthese have not yet been )ushed
by the !1* before dis)atching the gate, li$e cs;ss =ereG
Fnot sho=nG )uts fsb and gsb to the stac$
determine =hether the tra);interru)t ha))ened in $ernel Fby loo$ing at cs from
the tra) frameG.
(f not, call sBapgs and Fnot sho=nG reinitialiKe the segment regs, com)leting the
context s=itch to $ernel mode.
(n the end, initialiKe the frame)ointer =ith the trap frame address.
(n summary, all functions that enter the 0olaris $ernel =rite a common tra) frame
format. #ore exam)les on this =ill be given in cha)ter 6.
6.".1.The do!ble fa!lt handler
3he DK@ handler Ftra) ty)e !x8G is s)ecial. 7ouble faults occur if the !1* attem)ts a
)rivilege s=itch, but finds the $ernel Fring 5G stac$)ointer invalid so that the attem)t
116 6.0olaris;x86 architecture
to =rite the tra) return information Fthe bottom;HE )art of the tra)frame =ith the
registers cs;rip;O@?HNS;ss;rspG =ould cause a )agefault. :ernel stac$)ointer
corru)tions or $ernel stac$ overflo=s cause double faults.
3he gate that dis)atches the [7C handler therefore must be s)ecial. 0olaris uses/
a task gate in "2bit mode. 3he hard=are tas$ s=itch ?fixes@ the $ernel stac$)ointer
by recreating it from t6esp! of the double fault +11/
the 6.bit Interrupt 1tack +able FFSTG mechanism in 6.bit mode. 3he 6.bit 300
)rovides an array of seven alternate stac$)ointers that tra);interru)t gates can
select from. 3he use of the FST23 forces a stac$ s=itch even if the tra);interru)t is
not associated =ith a )rivilege s=itch, i.e. if it occurred in $ernel.
7 idt!48!::gate6desc
MH>K?EO SE? KP? P TSP FST
s;serrtrap $8 ! 4 int #
-oth mechanisms ensure that the double fault handler starts =ith a $no=n6good stac$.
6.".".Fast system alls in Solaris
#rhitet!re:optimEed lib
0olaris 15 on x86 )latforms detects the best available system call mechanism and
actually allo=s entry into the $ernel via one of the follo=ing methods/
6.bit )latforms are guarenteed to have the syscall;sysret instructions available.
3hey>re therefore used for system calls in 6.bit mode.
"2bit x86 !1*s by A#7 FAthlon and u)=ardsG have s;scall;s;sret.
A s)ecific "2bit libc that uses s;scall is )rovided for these !1*s.
"2bit x86 !1*s by (ntel F1entium6(( and u)=ardsG and other vendors have
s;senter;s;sexit. A s)ecific "2bit libc that uses s;senter is )rovided for these.
All "2bit x86 !1*s are guaranteed to allo= the ?classical@ x86 *&(+ system call
mechanism via the lcall ,!x$."! gate. 3his is su))orted as fallbac$.
6.0olaris;x86 architecture 117
6.'.Solaris=x86 2( arhitet!re - x86 H#T layer
3he role of the 0olaris HA3 Fhard$are address translationG layer is to )rovide
architecture6de)endent bac$end su))ort for the virtual memory subsystem. 4n all
architectures 0olaris su))orts, the follo=ing functions declared in C'm//at./7 =ill be
called from the generic )arts of the 8# subsystem 6 they must be )rovided by the HA3.
HA3 functionality falls into one of the follo=ing categories/
1. o)erations on =hole address s)aces.
Cunctions that allocate, free, s=a) in;out, du)licate )er6as hat structures or 9uery
usage statistics )er address s)ace fall into that category.
2. o)erations on )arts of address s)aces Franges of virtual addressesG.
Cunctions to ma);unma) Ftermed load;unloadG )hysical;device memory, functions
that loc$;unloc$ )hysical )ages corres)onding to a given virtual address range,
9uery;modify 8# attributes or )agesiKes, retrieve )hysical addresses F1C&sG and
share;unshare ma))ings bet=een t=o HA3s fall into this category.
". o)erations on )ages.
Cunctions to 9uery;modify attribute bits of a )age, functions to translate and
synchroniKe bet=een 8# attributes and architecture6de)endent ##* attributes,
and su))ort for softloc$ing belong here.
.. HA3 initialiKation and feature detection.
3he $ernel during startu) =ill call into these functions to initialiKe the architecture6
de)endent )art of the 8# subsystem, and to 9uery for su))ort of large )ages,
&*#A, FintimateG shared memory, and other features.
3he HA3 layer therefore decides ho= 0olaris 8# conce)ts Faddress s)aces, segments,
)agesG are ma))ed to a given ##* architecture/
(ts initialiKation is res)onsible for creating the $ernel address s)ace, enumerate
)hysical and device memory, and thereby also determines ho= the kernel #irtual
address space for a given architecture =ill loo$ li$e.
Cor a user #irtual address space, the A-( for the architecture decides =here code,
data, ma))ings or stac$s shall go, and of course the HA3>s hoo$s for address s)ace
du)lication;creation actually im)lement these rules =hen )rocess contexts are
created.
'iven that context s=itching bet=een )rocesses and;or $ernel also needs su))ort from
the HA3 to ?activate@ a ##* context, the HA3 =ill su))ly hoo$s to context s=itching
for this. 0ince context s=itching is also architecture6de)endent, this is not a standard
Farchitecture6inde)endentG HA3 interface, but directly called from the context
s=itching code for a s)ecific architecture.
6.'.1.the '"bit x86 H#T before Solaris 1@
6.'.".post:S1@ H#T
-oth the )ort to the 6.bit architecture and the need to su))ort ?modern@ 0olaris 8#
features on x86 )latforms re9uired a re=rite of the lo=6level 8# su))ort routines in
0olaris 15. 3he result =as a 8# architecture that both scales to terabytes of )hysical
memory and )rovides the follo=ing features =hich =ere not available on )re6015
versions of 0olaris;x86/
unified code;binary % no more se)arate mmu%$;mmu%6 modules to su))ort the
118 6.0olaris;x86 architecture
classical and 1AE ##* modes. 3he x86 HA3 is no= integrated in unix;genunix.
##* context management is highly sim)lified. (nstead of the threshold6based
context generation and )er6thread cr%, the ne= HA3 layer dynamically creates the
##* context register cr%.
su))ort for (0# and 7(0# Fflags SMM6SMHOE6MMQ and SMM6PHNEH:?EG
#100 Fmulti)le )age siKesG su))ort. 3he architecture allo=s .$- and 2#- F.#- in
non61AE modeG. 3his is accessible via the mechanisms mentioned in mpss.so.#0#1.
#14 F&*#A, latency grou)sG su))ort.
3he Hy)ertrans)ort6based memory architecture of the A#7 4)teron !1*s is non6
uniform because access latency de)ends on the number of H3 lin$s and ho)s to the
addressed memory ban$. *sers can access these features via liblgrp0%?F:1.
su))ort for PO<T6E9EC. A#7 4)teron !1*s $no= the ?&+@ )age attribute bit to
disable executability of a )age of memory % =hich is something that classical x86
!1*s could not do due to ?executability@ being an attribute of the code segment %
not the ##* )age. !lassical x86 therefore ignored PO<T6E9EC. 0ee cha)ter ".
4n !1*s that su))ort it, the 015 HA3 =ill automatically use and enforce it.
3he su))ort for PO<T6E9EC can brea$ legacy x86 a))lications that Fbeing bro$enG
assume every address to be executable even though PO<T6E9EC =asn>t re9uested for
a ma))ing. 0uch a))lications should be fixed, but in cases =here this is not )ossible
the HA3 honours a tunable in /etc/s;stem to disable PO<T6E9EC enforcement. Add
?set disable6>9[#@ in /etc/s;stem and reboot.
Additionally, the &+ bit is only available if the ##* is o)erating in 1AE mode.
0ince this is the only o)tion in 6.bit mode it can>t cause )roblems there. -ut even in
"2bit mode the 015 HA3 =ill default to using 1AE if it is available, in order to be
able to su))ort PO<T6E9EC, =hile in 0 and belo=, 1AE only =as enabled if either
re9uested ex)licitly or if the system had more then .'- of )hysical memory.
(ncom)atibilities e.g. =ith device drivers For 8#=are % a =ell6$no=n limitation of
the latter is that it doesn>t )rovide a guest 40 =ith 1AE su))ortG may re9uire to
s=itch off 1AE use in "2bit mode. 3his is )ossible by adding ?set
force6pae6off[#@ to /etc/s;stem.
3he x86 HA3 su))orts segkpm, i.e. the ability of the 0olaris $ernel to create a
com)lete in6$ernel ma))ing for all of )hysical memory in order to s)eed u)
user;$ernel data exchange and (;4.
3he su))ort for seg$)m is not 155Y com)lete % segmap Fthe 8# layer used to
buffer filesystem (;4G is not yet using seg$)m in the first6released version of 015.
#ost o)erations on the HA3 involve creating;locating;modifying )agetable entries Fi.e.
)age attributesG for a given virtual;)hysical address Ffor$ard and re#erse searchesG.
3he x86 ##* itself is a multi6level hashtable Ft=o levels for the classical "2bit ##*
mode, three levels for 1AE in "2bit mode and four levels for the 6.bit ##* modeG, so
searching the )hysical )age for a given virtual address could be done by =al$ing the
##* hash directly Fdoing a for=ard searchG.
-ut this is both inefficient and insufficient/
Eal$ing the )agetable lin$age re9uires u) to five memory loo$u)s and four hash
calculations to get the table indices Fassuming the 6.bit mode =ith four tablesG.
'iven that in most cases, the higher6level tables F1#<., 1713, 173G =ill be s)arse,
it>d be desirable to have a faster =ay to loo$ u) the )hysical location for a virtual
address.
1agetable addresses F)age frame numbersG are )hysical % not virtual. (n order to
6.0olaris;x86 architecture 11
search the )agetables directly, one =ould>ve to ma) them into virtual memory first.
A reverse search Ffind the virtual address a given )hysical )age is ma))ed to =ithin
a s)ecific ##* context ; address s)aceG is not )ossible using the x86 )agetables.
3he 0olaris;x86 HA3 solves these )roblems by introducing an abstraction layer on to)
of the )hysically6ma))ed )age tables % the H3able mechanism.
*nli$e ##* tables =hich are s)arse, H3ables are dense .
3here>s one H3able for every non6&*<< slot in the level ";2;1 ##* tables.
H3ables count the number of ma))ed entries, i.e. the number of non6&*<< 13Es in
their associated )age table.
H3ables allo= reverse searches % a level 5 htable Fcorres)onding to a ##*
)agetableG has an /t6parent )ointer at its level 1 htable, and so on.
H3ables are single6index hashed for fast ma))ing loo$u)s.
H3ables allo= fast for=ard searches F8A 1AG via the HA3>s htable hash, and Fslo=erG
reverse searches F1A 8AG via the /t6parent lin$age.
125 6.0olaris;x86 architecture
Illustration F ! (ntering the 1olaris/L kernel on %&' platforms
PML4[512]
pa ge ma p level t a ble
PP![512]
pa ge !irect or" point er t a ble
P![512]
pa ge !irect or" t able
P![512]
pa ge t a ble
"#$b%e&#
level #
"#$b%e&#
level $
"#$b%e&#
level %
"#$b%e&#
level &
'
(
L
L
'
(
L
L
'
(
L
L
'
(
L
L
'
(
L
L
'
(
L
L
'
(
L
L
pf)&#, page t ables' Sparse (rra"s )t ables' *ense +rees
"
#
&
p
$
r
e
)
#
"
#
&
p
$
r
e
)
#
"
#
&
p
$
r
e
)
#
*"#&pf)+,-x2--./ 0 11p#e
*pf)+11p#$b%e
'
(
L
L
'
(
L
L
'
(
L
L
'
(
L
L
'
(
L
L
"#&2$%id&c)#
, of chil!ren
"#&2$%id&c)#
, of chil!ren
"#&2$%id&c)#
, of chil!ren
'
(
L
L
'
(
L
L
'
(
L
L
'
(
L
L
'
(
L
L
'
(
L
L
(pa ges)
6.*.2irt!al (emory /ayo!t
-oth the "2bit and 6.bit $ernel on x86 share the address s)ace bet=een $ernel and
a))lications Fi.e. a :E2&E<-A0E )arameter existsG. Cor the "2bit virtual memory
layout, nothing has changed in 0olaris 15 vs. 0olaris . (f running on a 6.bit $ernel,
though, "2bit a))lications are no= able to use FalmostG all of the .'- virtual memory
available to them.
3he 6.bit virtual memory layout F$ernel;a))sG loo$s li$e this/
7 ::mappings J tail )r
:HSE ?FMFT SFUE >HME
2 +,-./+.0 ffffffffffc!!!!! ................ 3
.0-10/2-/+.0 ffffffffff8!!!!! ffffffffffc!!!!! &!!!!! kdebugseg
30,%0456076 fffffffffe8!!!!! ffffffffff!bc!!! 8bc!!! ktextseg
8alloc5base fffffffffa$!!!!! fffffffffe!!!!!! %e!!!!! k'alloc
core5base ffffffffc!!!!!!! fffffffffa$!!!!! %a$!!!!! k'seg6core
se9:;ap5start ffffffffbf!!!!!! ffffffffc!!!!!!! #!!!!!! kmapseg
se9:p5base ffffffffb$8!!!!! ffffffffbf!!!!!! c8!!!!! kpseg
:ernelheap fffffe8!!!!!!!!! ffffffffb$8!!!!! #.fb$8!!!!! k'seg
.0-3<=5/+.0 fffffe!!!!!!!!!! fffffe!!.feef!!! .feef!!! kpmseg
2 30,%04/+.0 fffffd8!!!!!!!!! fffffe!!!!!!!!!! 3 user!ernel red "one
#unmapped$
7 ffffffff8-!a!cf8::contextW ::mappings J tail )r
fffffd.fffdfb!!! fffffd.fffe!!!!! -!!! 2 anon 3
2 'a$+ 'a$+ 'ore libraries a$d a$o$ seg'e$ts ... 3 mappings and t%read stac!s
application stac!smappings gro&
do&n&ards to&ards '( %ole
2 !!!!8!!!!!!!!!!! ffff8!!!!!!!!!!! 3 address space %ole
application %eap gro&s up&ards to&ards '( %ole
(a%%li&atio$ hea%) &8a!!! aef!!! 66-!!! 2 anon 3
(a%%li&atio$ stati& data) &.*!!! &8a!!! ##!!! /usr/bin/amd6&/mdb
(a%%li&atio$ te,t) &!!!!! &6*!!! 6*!!! /usr/bin/amd6&/mdb
2 ! &!!!!! 3 lo&er red "one #unmapped$
0ee Cs;s/mac/param./7 for a detailed ex)lanation. 3he main elements are/
At the bottom end of the user 6.bit address s)ace is an unmapped 3)A page. 3his
is s)ecified by the A#76. *&(+ A-( % a))lication text load address is 2#-,
!x&!!!!!.
0olaris has chosen to give the maBority of the 6.bit 8A range to the a))lication.
3he user hea) =ill start after the a))lication text;data segments and gro=s
u)=ards into the 8A hole.
3he user stac$s and file ma))ings are created belo= :E2&E<-A0E and gro=
do=n into the 8A hole.
4ver all, a 6.bit a))lication on 0olaris 15 can ma) u) to Z2553- of memory.
At the top end of the user address s)ace is another unmapped 3)A page.
3he kernel address space begins at =EO>E?:HSE % =ith an unma))ed >huge> )age,
i.e. a &*<< 1#<. entry, 512'-. :ernel segments extend above that. 3he $ernel
itself currently occu)ies four slots in the 1#<. table, i.e. 23- virtual memory.
6.0olaris;x86 architecture 121
6.8.Context swithing
3a$ing a running thread off the !1* and resuming a )reviously slee)ing one is done
by the architecture6de)endent function resume01 in 0olaris. 4n x86 )latforms, this
executes code as given in the follo=ing flo= diagram/
3he code is fully )reem)tive. Ehen resume01 is entered, the old on)roc thread is
already 9uiesced Fits user registers have been savedG, but the stac$ =e>re running on
still belongs to old. Actions executed by resume01 in se9uence are/
1. (f the old thread Fi.e. the one currently mar$ed T6<>PO<C for this !1*G has context
o)s installed Fold)7t6ctx J[ >Q??G, the sa'ectx01 function from there =ill be
called. (f the thread hasn>t an extended context this can be by)assed.
A thread =ill have context o)s e.g. if it used floating )oint registers. 4n first use of
the C1* by a ne=ly6started thread, a tra) =ill occur and the tra) handler installs
context o)s for the thread that save;restore the floating )oint context.
2. -ecause )rocesses are free to create segments in their ?ocal Descriptor +able, the
$ernel has to change the <73 segment descri)tor in the !1*>s 'lobal 7escri)tor
3able so that its base address matches that of the ne> thread>s <73.
". 3he 8#;##* context Fuser ma))ingsG is still that of the old thread. (n order to
initialiKe the ##* in )re)aration for running ne>, /at6setup&t/read01 is called.
3his creates and activates the ##* context register cr% from ne>>s HA3.
.. Cloating )oint context saves Ffxsa'e instructionG on x86 )latforms are
asynchronous. (f the context o)s have $ic$ed off a floating )oint context save, =e>ll
no= =ait for that to finish FfBait instructionG.
3here is no ?Baitctx01@ context o) ... so this is inlined.
122 6.0olaris;x86 architecture
Illustration * ! steps in conte%t s$itching
resume0new1
inlined code to do/
t/read6lock0ne>1
inlined code to do/
t/read6unlock0old1
/at6setup&t/read0new1
sa'ectx0old1
restorectx0new1
set stac$)ointers for ne>/
$ernel rsp! in 300,
user esp;rsp
s=itch stac$ tem)orarily
to idle01>s stac$)ointer
CPQ)7cpu6gdt2?KTSE?3
is changed to match
ne>)7t6proc)7p6ldt
ne> has
context
o)s J
old has
context
o)s J
old
uses
C1* J
=ait for C1*
context save
set this !1*>s
current thread to ne>
CPQ)7cpu6t/read [ ne>W
restore registers
?return@ to ne>
ret
$o
+es
+es
$o
$o
+es
DONE !
5. (n order to remove de)endency on the old thread>s $ernel stac$)ointer, =hich is
still in use by interru)ts occurring during resume01, the stac$)ointer esp;rsp is
temporarily changed to that of this !1*>s idle thread.
6. All of the state of the old thread is no= saved and it can be )ut off the !1*.
T6<>PO<C =ill be removed from its t6flags, and the thread loc$ can be released.
Cor s)eed, the code to do this is inlined.
7. 3hreads currently executing on the !1* are loc$ed, so resume01 no= )erforms,
again inlined, a t/read6lock01 on ne>. 4nce done, it mar$s the thread T6<>PO<C.
8. curt/read a$a CPQ)7cpu6t/read still )oint to the old thread. 3his is no= changed.
. 3he ne> threads $ernel stac$)ointer is read from neB)7t6sp and )ut into the !1*>s
300, as =ell as into esp;rsp. Ee>re no longer running =ith idle01>s stac$ no=,
from here on interru)ts occuring =ill use ne>>s stac$.
15.3he return address is )ut on the stac$ and execution of ne> Fin $ernel modeG is
resumed via ret instruction. resume01 is done.
11.4nce the $ernel stac$ is un=inded, system call and;or tra) exit handling does
iret;s;sret;s;sexit F=hatever a))ro)riateG to continue execution in user mode.
6.0olaris;x86 architecture 12"
6.6.S!pporting (!ltiple CP4s
6.6.1./o,ing Primiti&es and #tomi Operations
6.6.".S(P $nterr!pt (anagement and Crossalls
6.6.'..4(#
12. 6.0olaris;x86 architecture
6.9.isaexe - Creating '"=6*bit:speifi appliations
6.0olaris;x86 architecture 125
9.Solaris=x86 Crashd!mp #nalysis
Crom ?3he 3ao of 1rogramming@/
+hus spake the master programmer:
NHhen you ha#e learned to snatch the error code from
the trap frame. it $ill be time for you to lea#e.N
9.1.)eb!gging tools for ore:=rashd!mp analysis
0olaris;x86, having been the ugly duc$ling for the longer )art of its history, received
much less attention by engineers doing debugging =or$ on $ernel6level than its
01A2! brethren. 3he choice of debugging tools for 0olaris;x86 therefore is much more
limited than for 0olaris;01A2! % unbundled Fi.e. not distributed =ith 0olaris itselfG
debugging tools used to be very uncommon, and still not all )ac$ages that see
fre9uent use on 01A2! have been )orted to 0olaris;x86. #ost notably, the 0olaris!A3
FscatG $ernel debugger that is very )o)ular both inside and outside of 0un is not FyetG
available under 0olaris;x86.
Cortunately, the set of debugging utilities shi))ed =ith 0olaris by default is available
for x86 and 01A2! architectures ali$e, =ith com)arable functionality % =hich has
gro=n significantly in 0olaris 15 com)ared =ith =hat =as available at the time of
0olaris 8. *seful utilities for $ernel debugging or core6 and crashdum) analysis under
0olaris 15 include/
3he modular debugger, mdb.
mdb is the main tool used for crashdum) analysis on 0olaris 15;x86. 3he default
feature set of mdb is generic and identical on 01A2! and x86 architectures. 0ince
mdb is extensively documented in the standard 0olaris manuals, the reader is
referred to those for details on mdb usage.
All exam)les given in the follo=ing sections =ill use mdb.
3here are s)ecial6)ur)ose versions of mdb available/
3he runtime $ernel debugger, kmdb. 3his version runs in $ernel context and
allo=s things li$e $ernel brea$6 and =atch)oints. kmdb is bundled =ith 0olaris % in
fact, enabling it at runtime can be done by calling mdb =ith the >)=> o)tion.
(nhanced mdb % mdb4. 3his is a feature6extended mdb that is distributed
internally at 0un as )art of the ken# debugging suite.
Cor those having to analyKe crashdum)s of 0olaris 8;x86 or 0olaris ;x86 systems,
the $env )ac$age and mdb4 have the advantage of su))lying Fmost ofG the
functionality that is there in mdb on 0olaris 15 but not on older bundled versions.
(utomate! Crash +ool % act. 3his )ac$age includes a loadable mdb module that
extends mdb =ith several dcmds, among them a ::findstack =or$ali$e that can
dis)lay function arguments % even in 6.bit mode. Exam)les later.
3he dynamic tracing frame=or$, dtrace.
Ehile dtrace itself isn>t targeted s)ecifically at )ost6mortem analysis, it>s of course
available on 0olaris;x86 % the feature set is generic, i.e. dtrace scri)ts =ill mostly be
)ortable bet=een 0olaris;01A2! and 0olaris;x86. mdb is able to extract dtrace
records from crashdum)s, in case the system )aniced during tracing.
3he proc tools. 0ome of them Fe.g. pmapG o)erate on crash6 and;or coredum)s =hile
others are again targeted at runtime a))lication analysis. Again, the )tools are
generic and available for "2;6.bit 01A2!;x86.
Cor a))lication coredum) analysis only, the dbx F0un Eor$sho)G and gdb F'&*G
7.0olaris;x86 !rashdum) Analysis 127
debuggers are both available in "2bit and 6.bit versions for 0olaris 15;x86. 1eo)le
familiar =ith either =on>t need to re6learn =hen loo$ing at a))lication coredum)s.
3he default disassembler, /usr/ccs/bin/dis. 3o ins)ect com)iler6generated
assembly code in binaries or dum)s, dis can be a useful tool, but it isn>t usable
interactively and =on>t see much use in )ost6mortem analysis. (ts biggest advantage
is that it allo=s sim)le ins)ection of machine code along =ith the disassembler
out)ut, since by default it dis)lays instruction binary code and mnemonic side by
side.
3his selection is biased to=ards crashdum) analysis and $ernel debugging and by no
means com)lete. 1lease refer to material on generic lo=6level troubleshooting on
0olaris for more choice ...
9.1.1.The Solaris=x86 boot deb!gger before Solaris 1@
128 7.0olaris;x86 !rashdum) Analysis
9.".Tro!bleshooting system hangs on Solaris=x86
#achines based on x86 !1*s do not have the 01A2!6style 4-1 interface that allo=s
lo=6level system interaction from the ?o$ )rom)t@. 3his of course means that there is
no e9uivalent on x86 )latforms for either the CStop4H7 $ey combination to enter 4-1
interaction mode or the s;nc 4-1 command that forces a system crashdum) to be
=ritten.
-y default, 0olaris;x86 machines have no ca)ability for ?brea$@ing the system. 3he
machine ignores $eyboard or serial line brea$ se9uences.
3he )resence of the $ernel debugger, kadb F)re60olaris 15G, kmdb F0olaris 15 and
laterG, is therefore a )rere9uisite.
9.".1./oading the ,ernel deb!gger - kadb=kmdb
3he $ernel debugger on 0olaris;x86 can be automatically loaded during boot using the
eeprom0#M1 command/
4n 0olaris and belo=/
eeprom boot)file[kadb
4n 0olaris 15 and above/
eeprom boot)file[kmdb
eeprom boot)args[)k FsuggestedG
3he disadvantage to this is that it re9uires a reboot in order to activate the $ernel
debugger. 4n 0olaris 15, one of the enhancements in kmdb therefore is the ability to
load the $ernel debugger at runtime. *se/
mdb )=
Fca)ital :G as root user to load kmdb at any time. 3he system =ill dro) to the $mdb
)rom)t and can be continued, :c, to resume execution.
4nce the debugger is loaded via either of the above =ays, it =ill catch C@#4H7 Fif a
gra)hics console is used % there is no CStop7 $ey on 1! $eyboardsG, res). serial brea$s
Fif a serial console is usedG.
Also, the alternate brea$ se9uence, kdb )a" can then be set.
&ote that on x86 systems, fe= gra)hics drivers su))ort s=itching to textmode =hen
the user )resses C@#4H7 to enter the $ernel debugger. 3he system =ill a))ear hung,
but kadb;kmdb is sitting invisibly in the bac$ground =aiting for in)ut. (t may be
necessary to ty)e debugger commands blindly A
9.".".Foring system rashd!mps
(n order to create forced crashdum)s from hung 0olaris;x86 systems, the follo=ing
methods are )ossible/
(f the system is soft hung and still allo=s interaction e.g. via console or net=or$
logins, sa'ecore )? Fto create a live crashdum) =ithout rebooting the machineG or
reboot )d Fto force a reboot together =ith a crashdum) being =rittenG can be used.
(f interaction is no longer )ossible, the $ernel debugger Fkadb;kmdbG must be used.
4n 0olaris;x86, console FscreenG logins use UC1DAV as the $eyboard brea$
se9uence, and serial consoles acce)t brea$s % )rovided the $ernel debugger has
been loaded.
4n the $ernel debugger>s )rom)t, a crashdum) can be forced using e.g. the
follo=ing method/
7.0olaris;x86 !rashdum) Analysis 12
Erite a &*<< into the eip;rip register, and continue/
!7eipW:c F"2bitG, or
!7ripW:c F6.bitG.
3he machine )anics immediately and dro)s to the debugger )rom)t again.
!ontinue another time,
:c
to =rite the crashdum) and have the system reboot.
3his is documented in 0un (nfo7oc [1555".
9.".'.Hard hangs on x86
3here are cases =here the attem)t to enter the $ernel debugger fails % the system is
then hard hung. -rea$ing out of hard hangs and forcing a crashdum) from one is not
al=ays )ossible, but the follo=ing techni9ues can be a))lied/
Enable the deadman timer. (f the follo=ing o)tion is set in /etc/s;stem/
set snooping[#
the high6resolution timer interru)t on the machine =ill count do=n a =atchdog
timer that is reset )eriodically by the 0olaris clock01 Flo=6resolution timerG code. (f
cloc$ )rocessing ; scheduling is stuc$, deadman =ill time out and cause a system
)anic.
3his is described in 0un (nfo7oc [1"258.
0ome machines may have an +(2;&#( Fe+ternally6(nitiated ; &on6#as$able
(nterru)tG s=itch. (f the system has a &#( s=itch, 0olaris can be told to use it via
the follo=ing /etc/s;stem )arameters/
set pcplusmp:apic6panic6on6nmi[# create a crashdum) on &#(
set pcplusmp:apic6kmdb6on6nmi[# enter $mdb interactively on &#(
0ince @)I interrupts cannot be blocked Fexce)t by the !1* disabling all
interru)tsG, this may brea$ out of hard hangs that not even deadman F=hich relies
on the high6resolution timer interru)tG can hel) =ith.
(n the future, 0un may )rovide a configurable &#( facility, to allo= o)tionally using
the system>s )o=er button as &#( s=itch on machines that su))ort A!1(.
3o in9uire about this, contact the 0olaris develo)ers via the mailing lists on
http://$$$.opensolaris.org.
9.".*.Setting !p the serial onsole on Solaris=x86
0ome x86 systems Fserver ty)e mainboards, for the most )artG su))ort serial consoles
on -(40 level. 3his is usually called console redirection, and if it is available it allo=s
interaction =ith the machine during the entire early stages of the boot )rocess % until
the 0olaris 2
nd
stage bootloader ta$es over.
3he 0olaris bootloader and $ernel must be told to use serial consoles % 0olaris;x86
)latforms =ill not default to using the serial line if no $eyboard is found. 3he re9uired
ste)s to set u) a serial console on 0olaris;x86 machines are as follo=s.
!onfigure, if available, the serial console redirection in the -(40. 0ince 1! -(40ses
don>t use the same defaults as 01A2! systems , it>s advisable to set the )arameters
to the usual defaults of 0olaris serial consoles, 655 -aud, 8bit, no )arity.
!onnect a serial line and test =hether you can interact =ith the -(40.
1"5 7.0olaris;x86 !rashdum) Analysis
&ext, boot 0olaris, into the De#ice 0onfiguration 5ssistant F7!AG.
4nce the follo=ing messages a))ear on the screen/
Ff t/e s;stem /ardBare /as c/anged" or to boot from a different
de'ice" interrupt t/e autoboot process b; pressing ESC.
)ress CESC7 to enter the 7!A.
1rogress through the 7!A to the ?Aoot 1olaris? screen.
0elect the @&6:oot6Tasks o)tion, then select the AieB/Edit Propert; Settings
o)tion from the menu and use @$6Continue.
0ome serial terminals don>t have function $eys or don>t submit the $eycodes
)ro)erly on the serial line. (n this case, CESC7 follo=ed by a digit can be used.
0croll do=n the menu and select input)de'ice, then use the @%6C/ange $ey to
change it to tt;a.
7o the same for output)de'ice, then go bac$ to ?Aoot +asks? using @$6:ack.
2eturn to ?Aoot 1olaris@ via @%6:ack, and continue there.
(f your -(40 does not allo= serial console redirection, 0olaris can still be configured to
use the serial line for in;out)ut % starting =ith the 7!A.
5. 4)en the file booten'.rc =ith a text editor.
4n a 0olaris;x86 that =as installed using screen;$eyboard, it can be found in
/boot/solaris/booten'.rc.
Cor a system that should be installed =ith 0olaris using a serial console, edit
booten'.rc on the 7!A flo))y, or in the 1+E boot environment if net=or$ boot is
used.
6. 0earch for the follo=ing t=o lines and have them refer to tt;a/
setprop output)de'ice[]tt;a]
setprop input)de'ice[]tt;a]
3his enables the serial console from the )oint on =here the 0olaris boot loader has
been started. -(40 interaction is not )ossible on such systems, but the serial console
under 0olaris =ill be o)erable.
7.0olaris;x86 !rashdum) Analysis 1"1
9.'.'"bit ,ernel rashd!mp analysis - a well:,nown
example
-efore =e dig dee) and use real6=orld exam)les of crashdum)s from actual re)orted
and fixed bugs, =e>ll create a crashdum) in a =ell6$no=n, controlled =ay. 4n a 0olaris
15;x86 system running a "2bit $ernel, )anic the system using the follo=ing command/
mdb )kB CCE>K
rootdir/P !
E>K
9.'.1.Pani messages
3he system very shortly after is going to )anic =ith messages similar to these/
After rebooting, the crashdum) is created and can be analyKed.
3he )anic message consists of the follo=ing three )arts/
3he )anic string itself. 3his tells =hich thread Fand on =hat !1*G =as running =hen
the system encountered the )anic. (n addition to that, it gives a ?)anic oneliner@
that>s either a deliberate message from callers of cmn6err0CE6PH>FC"...1, or the
generic :HK TOHP: ... message that>s )rinted during unex)ected $ernel faults. -ad
tra)s give the location of =here the general )ur)ose registers =ere saved at the
time of the tra) Fthe trap frame addressG in the rp[... field/
panic2cpu!3/t/read[d!!--6!!:
:HK TOHP: t;pe[e 0Dpf Page fault1 rp[d!#!dd88 addr[! occurred in module
IunixI due to a >Q?? pointer dereference
A )rintout of general6)ur)ose and !1* control register contents at the time of the
)anic. 3his is only meaningful for -A7 32A1s, and also only sho=n for -A7 32A1s.
1"2 7.0olaris;x86 !rashdum) Analysis
Illustration ! 1olaris/%&' panic messages on a F3bit kernel
p$)ic[cp3-]4#"re$d5d--556--1
78 !R8P1 #9pe5e (:pf P$ge f$3%#) rp5d-1-dd88 $ddr5- ;cc3rred i) <;d3%e
=3)ix= d3e #; $ '(LL p;i)#er derefere)ce
i).r;3#ed1
:pf P$ge f$3%#
7$d >er)e% f$3%# $# $ddr5-x-
pid592, pc5-xfe82-8-d, sp5-xfe8c-8f4, ef%$gs5-x1-246
cr-1 8--5--??*pg,@p,)e,e#,<p,pe+ cr41 6f8*x<<e,fxsr,pge,<ce,p$e,pse,de+
cr21 - cr?1 46-1-2-
gs1 d--4-1b- fs1 d-14---- es1 16- ds1 d-1?-16-
edi1 d-1-de1- esi1 cf$?A9f- ebp: d010dde4 esp1 d-1-ddb8
ebx1 - edx1 d--556-- ecx1 - e$x1 -
#rp1 e err1 2 eip1 fe82-8-d cs1 158
ef%1 1-246 3sp1 fe8c-8f4 ss1 -
d-1-dce8 3)ix1die+$A (e, d-1-dd88, -, -)
d-1-ddA4 3)ix1#r$p+fd1 (d-1-dd88, -, -)
d-1-dd88 3)ix1&c<)#r$p+8? ()
d010dde4 3)ix1<3#ex&e)#er+d (d-1-de1-, -, 1, -, )
d-1-de68 ge)3)ix1%;;>3p)$<e$#+54 (ceb5-d--, -, 1, -, )
d-1-df-c ge)3)ix12)&;pe)$#+6c (ceb5-d--, -, 1, 6, )
d-1-dfA- ge)3)ix1c;pe)+24f (ffd1955?, ceb5-d--,)
d-1-df88 ge)3)ix1;pe)+18 (ceb5-d--, -, 6, fec)
three different
stac$)ointers JAJA
)anicing instruction
bac$trace/
% frame)ointers
% return addresses
% arguments
address of saved registers
p$)ic[cp3-]4#"re$d5d--556--1
78 !R8P1 #9pe5e (:pf P$ge f$3%#) rp5d-1-dd88 $ddr5- ;cc3rred i) <;d3%e
=3)ix= d3e #; $ '(LL p;i)#er derefere)ce
i).r;3#ed1
:pf P$ge f$3%#
7$d >er)e% f$3%# $# $ddr5-x-
pid592, pc5-xfe82-8-d, sp5-xfe8c-8f4, ef%$gs5-x1-246
cr-1 8--5--??*pg,@p,)e,e#,<p,pe+ cr41 6f8*x<<e,fxsr,pge,<ce,p$e,pse,de+
cr21 - cr?1 46-1-2-
gs1 d--4-1b- fs1 d-14---- es1 16- ds1 d-1?-16-
edi1 d-1-de1- esi1 cf$?A9f- ebp: d010dde4 esp1 d-1-ddb8
ebx1 - edx1 d--556-- ecx1 - e$x1 -
#rp1 e err1 2 eip1 fe82-8-d cs1 158
ef%1 1-246 3sp1 fe8c-8f4 ss1 -
d-1-dce8 3)ix1die+$A (e, d-1-dd88, -, -)
d-1-ddA4 3)ix1#r$p+fd1 (d-1-dd88, -, -)
d-1-dd88 3)ix1&c<)#r$p+8? ()
d010dde4 3)ix1<3#ex&e)#er+d (d-1-de1-, -, 1, -, )
d-1-de68 ge)3)ix1%;;>3p)$<e$#+54 (ceb5-d--, -, 1, -, )
d-1-df-c ge)3)ix12)&;pe)$#+6c (ceb5-d--, -, 1, 6, )
d-1-dfA- ge)3)ix1c;pe)+24f (ffd1955?, ceb5-d--,)
d-1-df88 ge)3)ix1;pe)+18 (ceb5-d--, -, 6, fec)
(t>s a )retty)rint version of the saved registers at rp[.... 3he follo=ing com)arison
sho=s this clearly.
Cirst, the register dum) from the )anic message/
in.routed:
Dpf Page fault
:ad kernel fault at addr[!x!
pid[*$" pc[!xfe8$!8!d" sp[!xfe8c!8f&" eflags[!x#!$&6
cr!: 8!!-!!%%Cpg"Bp"ne"et"mp"pe7 cr&: 6f8Cxmme"fxsr"pge"mce"pae"pse"de7
cr$: ! cr%: &6!#!$!
gs: d!!&!#b! fs: d!#&!!!! es: #6! ds: d!#%!#6!
edi: d!#!de#! esi: cfa%.*f! ebp: d010dde4 esp: d!#!ddb8
ebx: ! edx: d!!--6!! ecx: ! eax: !
trp: e err: $ eip: fe8$!8!d cs: #-8
efl: #!$&6 usp: fe8c!8f& ss: !
0econd, ex)licitly )rinting the address given via rp[... as struct regs/
7 d!#!dd88::print )a Istruct regsI
V
d!#!dd88 r6gs [ !xd!!&!#b!
d!#!dd8c r6fs [ !xd!#&!!!!
d!#!dd*! r6es [ !x#6!
d!#!dd*& r6ds [ !xd!#%!#6!
d!#!dd*8 r6edi [ !xd!#!de#!
d!#!dd*c r6esi [ !xcfa%.*f!
d!#!dda! r6ebp [ 0xd010dde4
d!#!dda& r6esp [ !xd!#!ddb8
d!#!dda8 r6ebx [ !
d!#!ddac r6edx [ !xd!!--6!!
d!#!ddb! r6ecx [ !
d!#!ddb& r6eax [ !
d!#!ddb8 r6trapno [ !xe
d!#!ddbc r6err [ !x$
d!#!ddc! r6eip [ !xfe8$!8!d
d!#!ddc& r6cs [ !x#-8
d!#!ddc8 r6efl [ !x#!$&6
d!#!ddcc r6uesp [ !xfe8c!8f&
d!#!ddd! r6ss [ !
X
3he contents of the general6)ur)ose;segment register dum) from the )anic message
and the trap frame are obviously identical. -ut the register dum) contains more
information.
(t re)eats =hat the -A7 32A1 )anic string already sho=ed % it>s a )agefault, DP@ ;
ty)e 5xe in x86 terms, attem)ting to dereference a &*<< )ointer, addr[!. 3he
)rocess that ha))ened to be executing the code =as in.routed and it ran under
1(7 2. 3hat>s com)lementary information to the )anicing thread>s address that
the )anic message already has sho=n.
Cor a )agefault, as mentioned in cha)ter ", the )agefault address register, cr$,
=ill contain the fault address. 3his therefore must be identical =ith the addr[...
field % if the bad tra) =as a )agefault. 3he t=o values =on>t necessarily be e9ual
for bad tra)s of some other ty)e.
Ee also are given the address of the assembly instruction that actually caused the
bad tra). (t>s ex)licitly )rinted as pc[..., and, since on x86 the )rogram counter
is a register, the same value of course also found in the register dum);tra) frame
under eip. *nfortunately, the symbol name;offset is not given, so loo$ manually/
7 !xfe8$!8!d/ai
7.0olaris;x86 !rashdum) Analysis 1""
mutex6enter4!xd:lock cmpxc/gl edx"0ecx1
0everal stac$)ointers are given, sp[..., esp, and usp.
3he fields sp[... and usp are actually found to be e9ual.
-ut none of them is the stac$)ointer at the time of the )anic A
3he attem)t to bac$trace from either of them fails % no out)ut/
7 !xd!#!ddb8,C
7 !xfe8c!8f&,C
Ee also notice that the value of the saved esp register actually is the address of
the r6trapno field $ithin the trapframe A 3his value can>t have been the $ernel>s
esp before the tra) if it )oints at a location that only =as accessed after the tra)
actually occurred.
3his obviously needs some further ex)lanation. Ho= can one, in a "2bit 0olaris;x86
crashdum), find the stackpointer at the time $hen the trap occurred J
!ha)ter " has already given the ans=er % x86 !1*s, =hen encountering a tra)
=hile already running in pri#ileged mode, =on>t save esp;ss =hen =riting a
hard=are tra) frame % because the !1* doesn>t need to s=itch stac$s as it didn>t do
a )rivilege s=itch. (t uses =hatever the $ernel stac$)ointer =as and )uts the tra)
return information there. 3he first thing that is =ritten is eflags % not uesp;ss %
and the value of the stackpointer at the time of the panic must be deduced % as the
address of the =ord on the stac$ immediately before that. #ore on that later.
3he third )art is the )anic bac$trace/
d!#!dce8 unix:die4a. 0e" d!#!dd88" !" !1
d!#!dd.& unix:trap4fd# 0d!#!dd88" !" !1
d!#!dd88 unix:6cmntrap48% 01
d010dde4 unix:mutex6enter4d 0d!#!de#!" !" #" !" 1
d!#!de68 genunix:lookupnameat4-& 0ceb-!d!!" !" #" !" 1
d!#!df!c genunix:'n6openat46c 0ceb-!d!!" !" #" 6" 1
d!#!df.! genunix:copen4$&f 0ffd#*--%" ceb-!d!!"1
d!#!df88 genunix:open4#8 0ceb-!d!!" !" 6" fec1
12.Again, several of the values in there have already been seen on )revious )arts of
the )anic message/
:HK TOHP: t;pe[e 0Dpf Page fault1 rp[d!#!dd88 addr[! occurred in module2
... 3
edi: d!#!de#! esi: cfa%.*f! ebp: d010dde4 esp: d!#!ddb8
2 ... 3
trp: e err: $ eip: fe8$!8!d cs: #-8
2 ... 3
d!#!dd88 unix:6cmntrap48% 01
d010dde4 unix:mutex6enter4d 0d!#!de#!" !" #" !" 1
1. 3he address of the saved registers, rp[..., is re)orted as the framepointer of
6cmntrap01. 3his is =hy it is called trap frame.
2. 3he saved frame)ointer ebp from the )anic registers is also re)orted in the
stac$trace as the frame)ointer of the line in the bac$trace after the tra)frame.
". 0o is the faulting instruction>s address, eip, for =hich the corres)onding
symbolDoffset is sho=n in the bac$trace as =ell.
1".Cinally, =e note that in the stac$trace, different numbers of arguments are )rinted
by the debugger for different functions % e.g. four are sho=n for open01, t=o for
copen01, none for 6cmntrap01 or three for trap01.
Ho= does can the debugger $no= ho= many arguments a function has J
Eill it be correct about this, and ho= =ould =e verify J
1". 7.0olaris;x86 !rashdum) Analysis
9.'.".$mmediate a!se for the pani
+epetitori!m on '"bit x86 traps
<oo$ing at the data from the )anic messages, =e find that the )anic ha))ened
executing Bust the third instruction of mutex6enter01/
mutex6enter: mo'l gs:!x#!"edx
mutex6enter4.: mo'l !x&0esp1"ecx
mutex6enter4!xb: xorl eax"eax
mutex6enter4!xd: lock cmpxc/gl edx"0ecx1
<et>s try to understand this code % =hat does it do J
Cirst thing to notice is that this isn>t a function li$e most others % it doesn>t have a
function )rologue =here it>d initialiKe a frame)ointer or allocate stac$s)ace for itself.
3his obviously is )erformance6critical, hand=ritten assembly code. Cirst thing is does
is to load the =ord at address gs:!x#! into edx. As cha)ter 5 has sho=n, 0olaris
uses the Ygs segment for the current !1* structure, and offset !x#! there is
cpu6t/read. 0o gs:!x#! is sim)ly the 0olaris;x86 assembly version of curt/read. -ut
let>s verify this again, Bust to crosschec$. Ee get gs from the )anic messages/
panic2cpu!3/t/read[d!!--6!!:
2 ... 3
gs: d!!&!#b! fs: d!#&!!!! es: #6! ds: d!#%!#6!
2emember segment registers contain 16bit values only % the u))er 16bits of the
re)orted gs contents therefore are irrelevant. 4ur gs is !x#b!. 0ince the lo=er three
bits are clear, this is a )rivileged segment =ithin the '73, so =e need to find the '73
for the )anicing !1*. As the )anic message tells it>s !1* 5, so =e can loo$ into
struct cpu for this and find the '73 location from there/
7 ::cpuinfo
FK HKKO @?N >OQ> :SP? POF O>O> =O>O> SPFTCM TMOEHK PO<C
! fec$$%6& #b ! ! -* no no t)! d!!--6!! in.routed
7 ::offsetof cpu6t cpu6m
offsetof 0cpu6t" cpu6m1 [ !x&cc
7 fec$$%6&4!x&cc::print Istruct mac/cpuI mcpu6gdt
mcpu6gdt [ gdt!
7 gdt!4#b!::print user6desc6t usd6/ibase usd6midbase usd6lobase
usd6/ibase [ !xfe
usd6midbase [ !xc#
usd6lobase [ !xe88c
7 !xfec#e88c::B/att;pe
fec#e88c is fec#e88c4!" struct cpu 2#3
7 !xfec#e88c4#!/9 G ::B/atis
d!!--6!! is d!!--6!!4!" allocated as a t/read structure
3his fits % the segment descri)tor obviously )oints at the !1* structure, and the
on)roc thread for this !1* is the )anic thread. Yedx from the )anic registers,
ebx: ! edx: d!!--6!! ecx: ! eax: !
also confirms our analysis so far. 3he next instructions are/
mutex6enter4.: mo'l !x&0esp1"ecx
mutex6enter4!xb: xorl eax"eax
3he xorl obviously Keroes eax. 3he instruction before is not so obvious, but =e still
$no= =hat it does. (t loads the first argument of mutex6enter01 from the stac$.
2emember cha)ter 2/
-efore calling somebody else, a function in "2bit x86 )uts arguments on the stac$.
3he call instruction itself )uts a return address onto the stac$.
7.0olaris;x86 !rashdum) Analysis 1"5
At the time execution starts at the called function, 0esp1 is the return address, and
4&0esp1, 480esp1 and so on =ill be the arguments.
(n common functions, the )rologue =ill initialiKe a frame)ointer and argument access
after that is then done via ebp % but as indicated, mutex6enter01 doesn>t bother =ith
this and therefore uses esp directly.
And there =e are again % ho= can ( $no= =hat the stac$)ointer =as J 3he messages
sho= the >Q?? in ecx, but none of the ?stac$)ointers@ in the )anic messages is
consistent =ith that/
2 ... 3
:HK TOHP: t;pe[e 0Dpf Page fault1 rp[d!#!dd88 addr[! occurred in module IunixI
due to a >Q?? pointer dereference
2 ... 3
pid[*$" pc[!xfe8$!8!d" sp[!xfe8c!8f&" eflags[!x#!$&6
2 ... 3
edi: d!#!de#! esi: cfa%.*f! ebp: d!#!dde& esp: d!#!ddb8
ebx: ! edx: d!!--6!! ecx: ! eax: !
2 ... 3
7 !xfe8c!8f&4&/9
lookuppnat4!x*%:e8-%!c&%
7 d!#!ddb84&/9
!xd!#!ddbc: $
At &0esp1, neither gives &*<< so something isn>t right here % these addresses aren>t
stac$)ointers.
As mentioned before and in cha)ter ", the reason for this is the =ay "2bit x86 !1*s
create tra)frames if tra) handler and tra))ing instruction are running at the same
)rivilege level. (n "2bit x86/
.he stac9pointer at the time of the bad trap must be deduced indirectly.
2evisit cha)ter " and ho= tra) handling in x86 =or$s.
a tra) Fhard=are exce)tionG occurs.
the x86 !1* chec$s the corres)onding gate in its Interrupt Descriptor +able and
from there determines both/
the address of the tra) handler
the )rivilege level the handler =ill run at. Cor 0olaris, that>s ring 5 % $ernel mode.
If and only if the tra) occurred =hile the !1* =as executing code at a different
)rivilege level, the !1* =ill s=itch stac$s.
(n other =ords/ (f the tra) occurred in user mode, the !1* loads the $ernel stac$
)ointer Fand the $ernel stac$ segment registerG from its 300 structure and s=itches
to that.
In that case only, it =rites the )revious )rivilege level>s FuserG ss and FuserG esp
to the $ernel stac$.
-ut this =asn>t the case here. 3he tra) occurred in $ernel mode, and =e already
have a valid $ernel stac$ to start =ith. &o stac$ s=itch is done.
-efore the !1* finally dis)atches execution to the tra) handler, it =rites to the
stac$ the information needed to resume execution after handling it/
the contents of the E@?HNS register F)rocessor condition codes and stateG
the cs register and the address of the tra))ing instruction, eip.
0ince this =as a )agefault, an error code is =ritten as auxilliary information.
1"6 7.0olaris;x86 !rashdum) Analysis
4nly then =ill the gate entry )oint be $ic$ed off.
3his means that the hard=are )art of the tra) frame, E@?HNS;cs;eip, is =ritten
directly to =herever the $ernel stac$)ointer =as at the time of the tra).
Ehat ha))ens next J <et>s find out by loo$ing into the (73 for the DP@ Fty)e !xeG tra)/
7 ::offsetof cpu6t cpu6m
offsetof 0cpu6t" cpu6m1 [ !x&cc
7 ::offsetof Istruct mac/cpuI mcpu6idt
offsetof 0struct mac/cpu" mcpu6idt1 [ !x-8
7 !xfec#e88c4!x&cc4!x-8/9 G ::B/atis
fec#f#6! is idt!4! in unix]s data segment
7 fec#f#6!408Ee1::gate6desc
MH>K?EO SE? KP? P TSP ST=
pftrap #-8 ! 4 int !
7 pftrap::dis
pftrap: pus/l ,!xe
pftrap4$: Tmp )!x#d*c$ C6cmntrap7
0o the handler is pftrap01, =hich Bust )ushes the tra) number onto the stac$ and
then calls 6cmntrap01. 3hat>s the one =riting the tra) frame/
7 6cmntrap::dis
6cmntrap: pus/al
6cmntrap4#: subl ,!x#!"esp
6cmntrap4&: mo'B ds"!xc0esp1
6cmntrap48: mo'B es"!x80esp1
6cmntrap4!xc: mo'B fs"!x&0esp1
6cmntrap4!x#!: mo'B gs"!x!0esp1
6cmntrap4!x#&: cmpB ,!x#b!"!x!0esp1
6cmntrap4!x#b: Te 4!x#6 C6cmntrap4!x%#7
6cmntrap4!x#d: mo'B ,!x#6!"ax
6cmntrap4!x$#: mo'B ,!x!"cx
6cmntrap4!x$-: mo'B ,!x#b!"dx
6cmntrap4!x$*: mo'B eax"ds
6cmntrap4!x$b: mo'B eax"es
6cmntrap4!x$d: mo'B ecx"fs
6cmntrap4!x$f: mo'B edx"gs
6cmntrap4!x%#: mo'l esp"ebp
2 ... 3
6cmntrap4!x.e: call 4!x#.6f. Ctrap7
6cmntrap4!x8%: addl ,!xc"esp
3his code saves all eight general6)ur)ose registers to the stac$ using pus/al, then
reserves four more =ords of stac$s)ace and stuffs the not6yet6saved segment registers
ds..fs into there Fremember, cs and, if necessary, ss has already been saved by
the !1* before dis)atching the gate handlerG.
(t doesn>t =rite more to the stac$, and a little later initialiKes its frame)ointer. 3his of
course ex)lains =hy the )anic messages/
:HK TOHP: t;pe[e 0Dpf Page fault1 rp[d!#!dd88 addr[! occurred in module YunixZ
2 ... 3
d!#!dd88 unix:6cmntrap48% 01
sho= the address of the saved registers, rp[..., and the frame)ointer of 6cmntrap01
to be e9ual.
&o= the ans=er to ?=hat =as the stac$)ointer at the time of the tra)@ is easy. 7um)
the stac$, starting at the tra)frame, but this time sim)ly as data. All is there/
the segment registers ds..fs ex)licitly )ut there by 6cmntrap01
7.0olaris;x86 !rashdum) Analysis 1"7
the general6)ur)ose registers eax..edi =ritten via pus/al by 6cmntrap01
the tra) number, 5xe, )ushed by the gate entry, pftrap01
E@?HNS;cs;eip and the )agefault error code =ritten by the !1*
values )ushed before the tra) % the last one indicating the stac$)ointer =e =ant A
7 d!#!dd88"&!/nap
!xd!#!dd88: !xd!!&!#b! segment registers ds ...fs
!xd!#!dd8c: !xd!#&!!!! e%plicitly $ritten to the stack
!xd!#!dd*!: !x#6! by 6cmntrap01
!xd!#!dd*&: !xd!#%!#6!
!xd!#!dd*8: !xd!#!de#!
!xd!#!dd*c: !xcfa%.*f!
!xd!#!dda!: 0xd010dde4
!xd!#!dda&: !xd!#!ddb8 pus/al
!xd!#!dda8: !
st
instruction 6cmntrap01
!xd!#!ddac: !xd!!--6!!
!xd!#!ddb!: !
!xd!#!ddb&: !
!xd!#!ddb8: !xe $ritten by pftrap01
!xd!#!ddbc: $
!xd!#!ddc!: mutex6enter4!xd sa#ed to the stack by the 0:>
!xd!#!ddc&: !x#-8 before dispatching trap handler
!xd!#!ddc8: !x#!$&6
!xd!#!ddcc: lookuppnat4!x8f last pre!trap $ord on the stack
!xd!#!ddd!: !
!xd!#!ddd&: !
!xd!#!ddd8: !
!xd!#!dddc: !xceb-!d!!
!xd!#!dde!: !
0xd010dde4: !xd!#!de68
!xd!#!dde8: lookupnameat4!x-&
2 ... 3
!om)aring this =ith struct regs sho=s that the values there for ss;usp Fand also for
sp[... in the )anic messagesG are false )ositives. (n fact, they are the very last t=o
=ords =ritten to the stac$ before the )anic/
ra= data on the stac9 saved registers C struct regs
7 d!#!dd88"&!/nap
!xd!#!dd88:
!xd!#!dd88: !xd!!&!#b!
!xd!#!dd8c: !xd!#&!!!!
!xd!#!dd*!: !x#6!
!xd!#!dd*&: !xd!#%!#6!
!xd!#!dd*8: !xd!#!de#!
!xd!#!dd*c: !xcfa%.*f!
!xd!#!dda!: 0xd010dde4
!xd!#!dda&: !xd!#!ddb8
!xd!#!dda8: !
!xd!#!ddac: !xd!!--6!!
!xd!#!ddb!: !
!xd!#!ddb&: !
!xd!#!ddb8: !xe
!xd!#!ddbc: $
!xd!#!ddc!: mutex6enter4!xd
!xd!#!ddc&: !x#-8
!xd!#!ddc8: !x#!$&6
!xd!#!ddcc: lookuppnat4!x8f
7 d!#!dd88::print )a Istruct regsI
V
d!#!dd88 r6gs [ !xd!!&!#b!
d!#!dd8c r6fs [ !xd!#&!!!!
d!#!dd*! r6es [ !x#6!
d!#!dd*& r6ds [ !xd!#%!#6!
d!#!dd*8 r6edi [ !xd!#!de#!
d!#!dd*c r6esi [ !xcfa%.*f!
d!#!dda! r6ebp [ 0xd010dde4
d!#!dda& r6esp [ !xd!#!ddb8
d!#!dda8 r6ebx [ !
d!#!ddac r6edx [ !xd!!--6!!
d!#!ddb! r6ecx [ !
d!#!ddb& r6eax [ !
d!#!ddb8 r6trapno [ !xe
d!#!ddbc r6err [ !x$
d!#!ddc! r6eip [ !xfe8$!8!d
d!#!ddc& r6cs [ !x#-8
d!#!ddc8 r6efl [ !x#!$&6
d!#!ddcc r6uesp [ !xfe8c!8f&
1"8 7.0olaris;x86 !rashdum) Analysis
3
r
a
)

C
r
a
m
e
ra= data on the stac9 saved registers C struct regs
!xd!#!ddd!: !
2 ... 3
d!#!ddd! r6ss [ !
X
3he stac$)ointer before the )anic therefore must have been !xd!#!ddcc. At the
location =e =ere interested in, &0esp1, there is a >Q?? and this is consistent =ith
=hat =e see in the )anic registers. (t>s therefore clear no= that the code/
mutex6enter: mo'l gs:!x#!"edx
mutex6enter4.: mo'l !x&0esp1"ecx
mutex6enter4!xb: xorl eax"eax
mutex6enter4!xd: lock cmpxc/gl edx"0ecx1
had to )anic =hen the atomic com)are6and6exchange instruction tried to s=a) the
contents of the mutex =ith curt/read. 4bviously, a >Q?? )ointer =as )assed as mutex
address.
9.'.'.How to get there - !nderstanding the sta,trae
3he next ste) in analysis of this crashdum) is to examine =here this >Q?? )ointer
came from. 0ince =e =rote >Q?? into rootdir, =e $no= the ans=er to that already of
course, but =hat remains to be ex)lained is ho= this action of ours ex)lains the
sym)toms seen in the crashdum).
3he tas$ therefore is to $alk back the call history and identify =here the >Q?? that =as
)assed as an argument to mutex6enter01 =as ta$en from, and ultimately =hether
=hat =e find is consistent =ith the corru)tion of rootdir =e created deliberately. 3he
history of the )anic lies in the call )ath that lead to it, and that in turn is contained in
the stacktrace.
Ehat is a stac$trace J 0trictly s)ea$ing, the =ord is incorrect and =hat should be used
is call trace or backtrace. (t contains the list of functions called by a thread u) to a
certain )oint in time % in the case of the )anicing thread, of course, from the ma$ing
the system call to the )anic. As cha)ter 2 has sho=n, function calling in x86 via
call;ret uses the stac$ to save return addresses. -ecause most !1* architectures do
this, the =ords call trace, backtrace and stacktrace are used synonymously, and they
describe using the saved return addresses from the stac$ to reconstruct the calling
se9uence that lead to, in this case, the )anic.
A stac$trace =as already )rinted as )art of the )anic messages/
d!#!dce8 unix:die4a. 0e" d!#!dd88" !" !1
d!#!dd.& unix:trap4fd# 0d!#!dd88" !" !1
d!#!dd88 unix:6cmntrap48% 01
d010dde4 unix:mutex6enter4d 0d!#!de#!" !" #" !" 1
d!#!de68 genunix:lookupnameat4-& 0ceb-!d!!" !" #" !" 1
d!#!df!c genunix:'n6openat46c 0ceb-!d!!" !" #" 6" 1
d!#!df.! genunix:copen4$&f 0ffd#*--%" ceb-!d!!"1
d!#!df88 genunix:open4#8 0ceb-!d!!" !" 6" fec1
3he builtin ,C command of mdb allo=s us to re)rint the )anic stac$/
7 ,C
d010dde4 mutex6enter4!xd0d!#!de#!" !" #" !" d!#!df!!" !1
d!#!de68 lookupnameat4!x-&0ceb-!d!!" !" #" !" d!#!df!!" !1
d!#!df!c 'n6openat4!x6c0ceb-!d!!" !" #" 6" d!#!df6c" !1
d!#!df.! copen4!x$&f01
d!#!df88 open4!x#801
d!#!dfb& s;s6s;senter4!xe!01
3he ,C dcmd also acce)ts a frame)ointer as an argument, to start bac$tracing
arbitrary Fnot Bust the )anic thread>sG stac$s. (f =e give it the saved ebp from the
7.0olaris;x86 !rashdum) Analysis 1"
)anic registers, it gives/
2 ... 3
:HK TOHP: t;pe[e 0Dpf Page fault1 rp[d!#!dd88 addr[! occurred in module YunixZ
2 ... 3
edi: d!#!de#! esi: cfa%.*f! ebp: d010dde4 esp: d!#!ddb8
2 ... 3
7 d010dde4,C
d!#!de68 lookupnameat4!x-&0ceb-!d!!" !" #" !" d!#!df!!" !1
d!#!df!c 'n6openat4!x6c0ceb-!d!!" !" #" 6" d!#!df6c" !1
d!#!df.! copen4!x$&f01
d!#!df88 open4!x#801
d!#!dfb& s;s6s;senter4!xe!01
3hese three stac$traces are identical in the bottom )art but different for the to) fe=
frames that they sho=. -efore =e address the 9uestion =hy these are different and
=hich one Fif anyG is right, let>s first investigate t=o more basic things/
1. Ho= does bac$tracing =or$ at all J Ho= does the debugger do it, and =hat is the
meaning of the addresses and function names;offsets re)orted J
2. Ho= can the debugger $no= =hat function arguments are % and, as it seems, ho=
many arguments a function ta$es J Also, are these to be trusted J
0tac$ bac$tracing re9uires that function return addresses Fi.e. code locations =ithin a
function =here another function =as called, or =here execution is su))osed to resume
once the called function returnsG are )resent in the stac$. 3hat>s a given on the x86
architecture because of the =ay call;ret =or$s % by )ushing;)o))ing return address
to;from the stac$. -ut the information ?=here in function + =as function H called@
alone isn>t sufficient. 4nce a return address has been located in the stac$, a hint is
re9uired to find the next one % the debugger cannot, all by itself, $no= ho= many bytes
of stac$s)ace se)arate t=o consecutive return addresses. 3he stac$ is sim)ly an array
of stackframes that #ary in si8e.
3here are in )rinci)le t=o =ays ho= this can be solved/
1. #a$e the )ac$ed array of variable6siKed stac$frames into a lin$ed list, i.e. add a
?ne%t@ )ointer to every stac$frame.
(n order to )erform a bac$trace then, the debugger only needs to locate the lin$age
field and follo= that.
3his method =ill =or$ =ith "2bit x86 stac$s that use frame)ointers. #ore belo=.
2. 1rovide external information Fdebugging stabsG to the debugger about the frame
siKe for a given function.
3o )erform a bac$trace in this case, the debugger needs to loo$u) the framesiKe
information for a return address found, and add Fstac$s gro= do=n=ardG that to the
stac$ location of the return address in order to find the next return address.
3he advantage of this method of bac$tracing is that it can be made to =or$ even if
stac$frames aren>t lin$ed, i.e. that do not use frame)ointers. 3he disadvantage
clearly is that it re9uires external information that may or may not be available.
Ee>ll defer 2. till later =hen tal$ing about A#76. bac$tracing. As mentioned, the
)resence of frame)ointers, i.e. the =ay the function )rologue on "2bit x86 =or$s/
lookupnameat: pus/l ebp sa#e caller/s framepointer
lookupnameat4#: mo'l esp"ebp our ebp no$ points to caller/s ebp
2 ... 3
establishes a lin$age bet=een stac$frames % every frame)ointer in itself )oints to the
frame)ointer of the caller, and so on. Ehen =e dum) the stac$ as ra= data, =e
therefore find/
1.5 7.0olaris;x86 !rashdum) Analysis
panic2cpu!3/t/read[d!!--6!!:
:HK TOHP: t;pe[e 0Dpf Page fault1 rp[d!#!dd88 addr[! occurred in module IunixI
due to a >Q?? pointer dereference
2 ... 3
edi: d!#!de#! esi: cfa%.*f! ebp: d010dde4 esp: d!#!ddb8
2 ... 3
7 d!#!dd88"#!!/nap
2 ... 3
!xd!#!dda!: 0xd010dde4 ebp from trapframe
2 ... 3
!xd!#!ddc!: mutex6enter4!xd
!xd!#!ddc&: !x#-8
!xd!#!ddc8: !x#!$&6 end of trapframe
!xd!#!ddcc: lookuppnat4!x8f end of stack!before!trap
2 ... 3
0xd010dde4: 0xd010de68
!xd!#!dde8: lookupnameat4!x-&
2 ... 3
0xd010de68: 0xd010df0c
!xd!#!de6c: 'n6openat4!x6c
2 ... 3
0xd010df0c: 0xd010df70
!xd!#!df#!: copen4!x$&f
2 ... 3
0xd010df70: 0xd010df88
!xd!#!df.&: open4!x#8
2 ... 3
0xd010df88: 0xd010dfb4
!xd!#!df8c: s;s6s;senter4!xe!
2 ... 3
0xd010dfb4: !x#c%
!xd!#!dfb8: !
!xd!#!dfbc: !x#.%
!xd!#!dfc!: !x#.%
!xd!#!dfc&: 6
!xd!#!dfc8: !xcebd$!!!
!xd!#!dfcc: !x8!&..c!
!xd!#!dfd!: !xd!#!dfe&
!xd!#!dfd&: !xceb&6!!!
!xd!#!dfd8: !xceb#db.-
!xd!#!dfdc: !x8!&..a8
!xd!#!dfe!: -
!xd!#!dfe&: !x$!8
!xd!#!dfe8: !
!xd!#!dfec: !xceb#db.-
!xd!#!dff!: !x#6b
!xd!#!dff&: !x$8$
!xd!#!dff8: !x8!&..a8
!xd!#!dffc: !x#.%
mdb: failed to read data from target: no mapping for address
!xd!#!e!!!:
7.0olaris;x86 !rashdum) Analysis 1.1
<oo$s li$e another tra)frame A
3his is, of course, exactly the =or$ that mdb does automatically on ,C. !om)are/
Output of $ manually follo=ing framepointers
7 ,C
d!#!dde& mutex6enter4!xd02 ... 31
d!#!de68 lookupnameat4!x-&02 ... 31
d!#!df!c 'n6openat4!x6c02 ... 31
d!#!df.! copen4!x$&f01
d!#!df88 open4!x#801
d!#!dfb& s;s6s;senter4!xe!01
Cebp[9WCeip[pWCebp/n9p
d!#!dde&
mutex6enter4!xd
!xd!#!dde&:
d!#!de68 lookupnameat4!x-&
7 E./n9p
!xd!#!de68:
d!#!df!c 'n6openat4!x6c
7 E./n9p
!xd!#!df!c:
d!#!df.! copen4!x$&f
7 E./n9p
!xd!#!df.!:
d!#!df88 open4!x#8
7 E./n9p
!xd!#!df88:
d!#!dfb& s;s6s;senter4!xe!
7 E./n9p
!xd!#!dfb&:
#c% !
0o the bac$trace )rinted by mdb on ,C sim)ly consists of the frame)ointer;return
address )airs in the stac$.
Ee can also see that ,C, =hen )rinting the )anic thread>s stac$trace, uses ebp;eip
from the tra)frame to )rint as the first line. 3hat =ould be correct had the bad tra)
ha))ened =ithin a function that initialiKed a frame)ointer of its o=n % but
mutex6enter01, sim)le as the code is, doesn>t do that/
mutex6enter: mo'l gs:!x#!"edx
mutex6enter4.: mo'l !x&0esp1"ecx
mutex6enter4!xb: xorl eax"eax
mutex6enter4!xd: lock cmpxc/gl edx"0ecx1
mutex6enter4!x##: Tne 4!xbbb- Cmutex6'ector6enter7
mutex6enter4!x#.: ret
mutex6enter4!x#8: mo'l ,!x!"eax
3his of course means that the frame)ointer, ebp, at the time of the )anic, still =as
that of the caller of mutex6enter01. 7isassembly for the stac$frame immediately
belo= it also sho=s that the return address there isn>t from a call to mutex6enter01/
d!#!dde& mutex6enter4!xd0d!#!de#!" !" #" !" d!#!df!!" !1
d!#!de68 lookupnameat4!x-&0ceb-!d!!" !" #" !" d!#!df!!" !1
2 ... 3
7 lookupnameat4!x-&::dis
2 ... 3
lookupnameat4!x&f: call 4!x.* Clookuppnat7
lookupnameat4!x-&: addl ,!x#8"esp
0o ho= did =e get from lookuppnat01 to mutex6enter01 J
0im)ly follo= the code. 3he bad tra) ha))ened in mutex6enter4!xd, =ithout anything
else having been )ushed on the stac$ For the stac$)ointer changed directlyG by that
function. 3his means % the stac$)ointer esp at the time of the )anic, in this case,
)oints to the return address into the caller of mutex6enter01/
1.2 7.0olaris;x86 !rashdum) Analysis
7 d!#!dd88"&!/nap
!xd!#!dd88:
!xd!#!dd88: !xd!!&!#b!
!xd!#!dd8c: !xd!#&!!!!
!xd!#!dd*!: !x#6!
!xd!#!dd*&: !xd!#%!#6!
!xd!#!dd*8: !xd!#!de#!
!xd!#!dd*c: !xcfa%.*f!
!xd!#!dda!: 0xd010dde4
!xd!#!dda&: !xd!#!ddb8
!xd!#!dda8: !
!xd!#!ddac: !xd!!--6!!
!xd!#!ddb!: !
!xd!#!ddb&: !
!xd!#!ddb8: !xe
!xd!#!ddbc: $
!xd!#!ddc!: mutex6enter4!xd
!xd!#!ddc&: !x#-8
!xd!#!ddc8: !x#!$&6
!xd!#!ddcc: lookuppnat4!x8f
!xd!#!ddd!: !
2 ... 3
7 lookuppnat4!x8f::dis
2 ... 3
lookuppnat4!x8*: pus/l ebx
lookuppnat4!x8a: call )!xa!!ef Cmutex6enter7
lookuppnat4!x8f: addl ,!x&"esp
9.'.*.Finding f!ntion arg!ments
3he next 9uestion to address is ho= the debugger finds arguments =hen dis)laying
the bac$trace, =hether they>re correct and in case they>re not, ho= =e can find the
real function arguments manually.
(t has already been sho=n that mdb>s ,C dcmd in "2bit x86 )rints different numbers of
arguments for different functions. -efore =e do this for the )anic thread, let>s first
loo$ at a more6com)licated stac$trace that illustrates the underlaying )rinci)les
better/
7 cff#*d!!,C
cff#*d#c sBtc/4!x##*01
cff#*d&! c'6Bait6sig4!x##*0cf8%!c#6" cf8%a*6&1
cff#*d-& str6c'6Bait4!x8$0cf8%!c#6" cf8%a*6&" ffffffff" !1
cff#*d88 strBait+4!x#a60cf8%a*#8" $" 8!" %" ffffffff" cff#*dd81
cff#*ddc strread4!x##60cf8%%c!!" cff#*f%c" ceefff%81
cff#*df8 iBscnread4!x%*01
cff#*e!c cde'6read4!x$$0%8!!!!" cff#*f%c" ceefff%81
cff#*e%8 cnread4!x&!01
cff#*e&c cde'6read4!x$$0!" cff#*f%c" ceefff%81
cff#*e*! spec6read4!x$!801
cff#*eac fop6read4!x#b0cfe$ec!!" cff#*f%c" !" ceefff%8" !1
cff#*f88 read4!x#f*01
cff#*fb& s;s6s;senter4!xe!01
mdb in the bac$trace above sho=s bet=een t=o and six function arguments. Crom
deduction, =e already see that it cannot be fully correct about =hat it sho=s. Cor
exam)le, read0*e1 functions, li$e all those Eread01 above, ta$e three arguments as
)er the 77( interface s)ecification, but the debugger sho=s bet=een Kero and four
=hich cannot be right.
Ee $no=, from the =ay stac$s on "2bit x6 =or$, that arguments are )assed on the
7.0olaris;x86 !rashdum) Analysis 1."
3
r
a
)

C
r
a
m
e
stac$)ointer %esp
immediately before the )anic
stac$ and functions access them via 480ebp1 on=ards. 3his is of course =hat mdb
does above. 8erify it/
2 ... 3
cff#*d-& str6c'6Bait4!x8$0cf8%!c#6" cf8%a*6&" ffffffff" !1
2 ... 3
cff#*d88 strBait+4!x#a60cf8%a*#8" $" 8!" %" ffffffff" cff#*dd81
2 ... 3
7 cff#*d-&48"&/n9
!xcff#*d-c:
cf8%!c#6
cf8%a*6&
ffffffff
!
7 cff#*d8848"6/n9
!xcff#*d*!:
cf8%a*#8
$
8!
%
ffffffff
cff#*dd8
-ut =here does mdb get the idea from ho= many arguments it should )rint J And =hy
is it off in some cases J
3he ans=er to that lies in the return addresses, or rather in the instructions that they
)oint to. Ee find/
return addressesAarguments Instr. at ret. addr.
7 cff#*d!!,c
sBtc/4!x##*01
c'6Bait6sig4!x##*0cf8%!c#6" cf8%a*6&1
str6c'6Bait4!x8$0cf8%!c#6" cf8%a*6&" ffffffff" !1
strBait+4!x#a60cf8%a*#8" $" 8!" %" ffffffff" cff#*dd81
strread4!x##60cf8%%c!!" cff#*f%c" ceefff%81
iBscnread4!x%*01
cde'6read4!x$$0%8!!!!" cff#*f%c" ceefff%81
cnread4!x&!01
cde'6read4!x$$0!" cff#*f%c" ceefff%81
spec6read4!x$!801
fop6read4!x#b0cfe$ec!!" cff#*f%c" !" ceefff%8" !1
read4!x#f*01
s;s6s;senter4!xe!01
addl ,!x&"esp
mo'(Bl !x#80ebx1"eax
addl ,!x8"esp
addl ,!x#!"esp
addl ,!x#8"esp
addl ,!xc"esp
mo'l ebp"esp
addl ,!xc"esp
mo'l ebp"esp
addl ,!xc"esp
mo'l ebp"esp
addl ,!x#&"esp
xorl ecx"ecx
Ee notice that/
1. mdb )rints arguments for those functions =here the return address to the caller
)oints to an instruction addl ..."esp.
(t does not )rint arguments for functions =here the return address to the caller
)oints to some other instruction.
Exam)le/
read01 calls fop6read01, and the return address into read4... for that call
)oints to addl ,!x#&"esp. mdb )rints arguments for fo)SreadFG.
fop6read01 calls spec6read01, but no= the return address to fop6read4...
)oints to some other instruction. mdb )rints no arguments for spec6read01.
2. 3he number of arguments dis)layed is deduced from the siKe of the 1
st
o)erand of
the addl ..."esp.
1.. 7.0olaris;x86 !rashdum) Analysis
3he debugger uses the fact that in many cases, com)iler6generated code =ill clean up
the stack after return from a function call. 3his means that code that calls a function
=ith & arguments Fand therefore )ushes & "2bit =ords to the stac$ before callG =ill
need to remove these & arguments from the stac$ again. (n order to do that, the code
)o)s them to no=here by ex)licitly adding .W& -ytes to the stac$)ointer. <i$e this/
strread4!xfd: leal )!x&0ebp1"eax
strread4!x#!!: pshl !eax
strread4!x#!#: pshl "'0x1
strread4!x#!%: mo'sBl !x#&0edi1"eax
strread4!x#!.: pshl !eax
strread4!x#!8: pshl 0x20$!edi&
strread4!x#!b: mo'sbl )!x$80ebp1"eax
strread4!x#!f: pshl !eax
strread4!x##!: pshl !ebx
strread4!x###: call 4!xba%d CstrBait+7
strread4!x##6: addl "0x18?!esp
(.e. =e>ve )ushed six arguments for strBait+01, and remove 6W.X5x18 -ytes from the
stac$ after return from that function call.
As the exam)le above has already sho=n, it>s nothing more than code generation
convention Fand not mandated by the i"86 *&(+ A-(G that the return address shall
)oint to an addl instruction that cleans u) the stac$. 3he com)iler on o)timiKing code
can decide to )ut something else in there and decide to do the stac$ cleanu) later For
not at all, i.e. leave it for the function e)ilogueG.
0o, for cases =here the debugger does not re)ort arguments, ho= can =e find ho=
many arguments the function actually has J 3here are t=o indirect =ays of doing it/
1. <oo$ at the assembly code of the caller and count the PQSM instructions that =ere
done before the call. As an exam)le, the follo=ing code for fop6read01 )roves it
has )assed five arguments to spec6read01/
2 ... 3
cff#*e*! spec6read4!x$!801
cff#*eac fop6read4!x#b0cfe$ec!!" cff#*f%c" !" ceefff%8" !1
2 ... 3
7 fop6read::dis
fop6read: pus/l ebp
fop6read4#: mo'l esp"ebp
fop6read4%: mo'l !x80ebp1"ecx
fop6read46: mo'l !x$80ecx1"eax
fop6read4*: mo'l !xc0eax1"eax
fop6read4!xc: pshl 0x18$!ebp&
fop6read4!xf: pshl 0x14$!ebp&
fop6read4!x#$: pshl 0x10$!ebp&
fop6read4!x#-: pshl 0xc$!ebp&
fop6read4!x#8: pshl !ecx
fop6read4!x#*: call Eeax
fop6read4!x#b: mo'l ebp"esp
fop6read4!x#d: popl ebp
fop6read4!x#e: ret
2. !hec$ the assembly code for the called function and see ho= many 4...0ebp1
references it ma$es. 0ince =e $no= the function accesses its arguments using the
frame)ointer, 480ebp1 on=ards, this allo=s us to count ho= many arguments it
actually uses. (t>s )ossible for a function to ignore some of its arguments, but of
course it>d be bad if it used more args than =ere )assed in. (n that sense, chec$ing
for the numbers of arguments used is a com)lementary consistency chec$ com)ared
to chec$ing the number of arguments )assed in.
7.0olaris;x86 !rashdum) Analysis 1.5
A))lying this techni9ue to spec6read01 as above tells us it uses three arguments,
80ebp1, c0ebp1, and !x#&0ebp1. (t ignores its third arg, 4!x#!0ebp1, and any
arg )ast the fourth.
7 spec6read::dis J egrep ]2a)3!x2!)*a)f34^0ebp]
spec6read4!xd: mo'l !x80ebp1"esi
spec6read4!x&!: pus/l !x#&0ebp1
spec6read4!x&%: pus/l !xc0ebp1
spec6read4!x-6: mo'l !xc0ebp1"edi
spec6read4!xf#: mo'l !xc0ebp1"esi
spec6read4!x#fb: pus/l !x#&0ebp1
4f course, if =e =ant to find the five arguments that =ere )assed to spec6read01
above, =e can dum) them from memory starting at 480ebp1/
2 ... 3
cff#*e*! spec6read4!x$!801
2 ... 3
7 cff#*e*!48"-/n9
!xcff#*e*8:
cfe$ec!!
cff#*f%c
!
ceefff%8
!
Ouod erat demonstrandum A
&o= let>s revisit the )anic bac$trace/
7 ,C
d!#!dde& mutex6enter4!xd0d!#!de#!" !" #" !" d!#!df!!" !1
d!#!de68 lookupnameat4!x-&0ceb-!d!!" !" #" !" d!#!df!!" !1
d!#!df!c 'n6openat4!x6c0ceb-!d!!" !" #" 6" d!#!df6c" !1
d!#!df.! copen4!x$&f01
d!#!df88 open4!x#801
d!#!dfb& s;s6s;senter4!xe!01
3his sho=s another oddity/ mdb doesn>t dis)lay more than six arguments even though
some of the functions above ta$e more than that. Cor exam)le, Cs;s/'node./7
declares the function )rototy)e/
int 'n6openat0c/ar Epnamep" enum uio6seg seg" int filemode" int createmode"
struct 'node EE'pp" enum create crB/;"
mode6t umask" struct 'node Estart'p1W
=hich ta$es eight arguments. 3he return address/
7 copen4!x$&f/i
copen4!x$&f: addl ,!x$!"esp
confirms this F8W. X "2 X 5x25G. 3his is mdb>s default setting % )rint no more than six
arguments in stac$traces. 3he user can override this by giving the number of args to
)rint Fif )ossibleG as additional o)tion/ ,C ... % see belo=.
0ummary/
3he debugger determines the number of arguments to )rint from ins)ecting the
instruction at the return address. (f this adBusts the stac$)ointer via addl, then
the 1
st
o)erand is used as the number of stac$ =ords to )rint
mdb )rints at most six arguments by default. 3hat>s a deliberate limitation % it
can be overridden. Rust s)ecify the maximum number of arguments to )rint as
additional )arameter to ,C/
1.6 7.0olaris;x86 !rashdum) Analysis
7 ,C #!
d!#!dde& mutex6enter4!xd0d!#!de#!" !" #" !" d!#!df!!" !1
d!#!de68 lookupnameat4!x-&0ceb-!d!!" !" #" !" d!#!df!!" !1
d!#!df!c 'n6openat4!x6c0ceb-!d!!" !" #" 6" d!#!df6c" !" #$" !1
d!#!df.! copen4!x$&f01
d!#!df88 open4!x#801
d!#!dfb& s;s6s;senter4!xe!01
(f the debugger )rints arguments, they can be considered correct because they are
on the stac$ and ! code is su))osed to treat its arguments read6only. #eaning the
area on the stac$ =here the arguments of a function are =ill not be modified by this
function during its lifetime.
(f the debugger does not )rint arguments, it means the return address =as found
not to be an addl instruction. (n this case/
disassemble the caller to see ho= many arguments it )ushes to the stac$
disassemble the called function to see ho= many arguments it accesses, i.e. ho=
many 480ebp1 on=ards references it has in its assembly code.
use the framepointer Fthe address )rinted to the left of the return instruction in
stac$traces from ,C or ::findstackG and dum) & "2bit =ords of memory starting
at 480ebp1.
9.'.8.Pieing it all together
&o= let>s determine the rootcause for this )anic. Ee already $no= the -A7 32A1
occurred because mutexSenterFG =as called =ith a &*<< as argument. 3his is found in
the stac$/
2 ... 3
!xd!#!ddbc: $
!xd!#!ddc!: mutex6enter4!xd
!xd!#!ddc&: !x#-8
!xd!#!ddc8: !x#!$&6
!xd!#!ddcc: lookuppnat4!x8f
!xd!#!ddd!: !
and the code that calls mutex6enter01,
lookuppnat4!x8*: pus/l ebx
lookuppnat4!x8a: call )!xa!!ef Cmutex6enter7
lookuppnat4!x8f: addl ,!x&"esp
together =ith the value of ebx from the saved registers/
7 d!#!dd88::print )a Istruct regsI
V
2 ... 3
d!#!dda8 r6ebx [ !
2 ... 3
7 ::msgbuf
2 ... 3
ebx: ! edx: d!!--6!! ecx: ! eax: !
2 ... 3
)roves =e>re loo$ing at the ?right@ >Q??. 3he tas$ therefore is no= to evaluate =here
that >Q?? )ointer came from. Ee disassemble lookuppnat01 for that )ur)ose and
chec$ =here it ta$es ebx from/
7 lookuppnat::dis J grep ebx
lookuppnat46: pus/l ebx
7.0olaris;x86 !rashdum) Analysis 1.7
stac$)ointer %esp
immediately before the )anic
4(%esp)
argument of <3#ex&e)#er()
lookuppnat4!x$-: popl ebx
lookuppnat4!x..: mo'l !x#c0ebp1"ebx
lookuppnat4!x.a: testl ebx"ebx
lookuppnat4!x.e: mo'l !x&&c0esi1"ebx
lookuppnat4!x86: mo'l )!x&0ebp1"ebx
lookuppnat4!x8*: pus/l ebx arg of mutex6enter01 comes from %ere )
lookuppnat4!x*$: incl !xc0ebx1
lookuppnat4!x*-: pus/l ebx
lookuppnat4!xcf: pus/l ebx
lookuppnat4!xed: popl ebx
3he pus/ and pop instructions )robably are )arts of )rologues;e)ilogues. 3he testl
doesn>t modify ebx, so =e>re left =ith the follo=ing three that =e need to chec$
further/
2 ... 3
lookuppnat4!x..: mo'l !x#c0ebp1"ebx
lookuppnat4!x.e: mo'l !x&&c0esi1"ebx
lookuppnat4!x86: mo'l )!x&0ebp1"ebx
3he first one is an access to the 6
th
argument to lookuppnat01. Ee get that from the
stac$, using the frame)ointer that =e $no=/
7 d!#!dde&4#c/9
!xd!#!de!!: !
Hmm, so there>s a >Q?? in there. <et>s cheat and chec$ sources, Cs;s/pat/name./7/
extern int lookuppnat0struct pat/name E" struct pat/name E" enum s;mfolloB"
'node6t EE" 'node6t EE" 'node6t E1W
3hat>d be a )ossibly valid )lace =here a mutex address could come from, because the
'node6t data structure>s first member, '6lock is a mutex. -ut then, the others can not
yet be excluded. <et>s chec$ the assembly code again/
lookuppnat4!x..: mo'l !x#c0ebp1"ebx
lookuppnat4!x.a: testl ebx"ebx
lookuppnat4!x.c: Tne 4!xd Clookuppnat4!x8*7
lookuppnat4!x.e: mo'l !x&&c0esi1"ebx
lookuppnat4!x8&: Tmp 4!x- Clookuppnat4!x8*7
lookuppnat4!x86: mo'l )!x&0ebp1"ebx
lookuppnat4!x8*: pus/l ebx
lookuppnat4!x8a: call )!xa!!ef Cmutex6enter7
lookuppnat4!x8f: addl ,!x&"esp
Eell % =e load arg[6 into ebx, chec$ =hether it>s >Q?? % and only go on to call
mutex6enter01 on it if it is not % Tne. Ee cannot have ta$en that first )ath.
3he second occurance ta$es ebx from !x&&c0esi1. #a$ing the assum)tion that =e>d
gone do=n that )ath, =e $no= that esi =ouldn>t have changed bet=een the above
)lace and the time the )anic occurred, and therefore =e can use its value from the
tra)frame;saved registers to chec$ =hat>s in !x&&c0esi1/
7 d!#!dd88::print )a Istruct regsI
V
2 ... 3
d!#!dd*c r6esi [ !xcfa%.*f!
2 ... 3
7 ::msgbuf
2 ... 3
edi: d!#!de#! esi: cfa%.*f! ebp: d!#!dde& esp: d!#!ddb8
2 ... 3
7 !xcfa%.*f!4&&c/9
!xcfa%.e%c: cf6.*d8!
7 cf6.*d8!::B/atis
1.8 7.0olaris;x86 !rashdum) Analysis
cf6.*d8! is cf6.*d8!4!" allocated from 'n6cac/e
3his value is a vnode, and it>s not >Q?? % so =e cannot have gone do=n that code)ath
either. <eaves only the third )ossibility, )&0ebp1. 3he >Q?? must have come from this
local variable of lookuppnat01. 3he stac$ contents sho= this is >Q??/
7 d!#!dde&)&/9
!xd!#!dde!: !
&o= chec$ the assembly code for )laces =here lookuppnat01 modifies this value/
7 lookuppnat::dis J egrep )e ])!x&^0ebp^1,]
lookuppnat4!x%b: mo'l eax")!x&0ebp1
lookuppnat4!x6c: mo'l eax")!x&0ebp1
7isassemble around these areas to find out more/
7 lookuppnat4!x%b::dis
lookuppnat4!x$%: popl edi
lookuppnat4!x$&: popl esi
lookuppnat4!x$-: popl ebx
lookuppnat4!x$6: mo'l ebp"esp
lookuppnat4!x$8: popl ebp
lookuppnat4!x$*: ret
lookuppnat4!x$a: pus/l !x80esi1
lookuppnat4!x$d: call )!xa!!*$ Cmutex6enter7
lookuppnat4!x%$: addl ,!x&"esp
lookuppnat4!x%-: mo'l !x&-!0esi1"eax
lookuppnat4!x%b: mo'l eax")!x&0ebp1
lookuppnat4!x%e: testl eax"eax
lookuppnat4!x&!: Te 4!x$. Clookuppnat4!x6.7
2 ... 3
7 lookuppnat4!x6c::dis
2 ... 3
lookuppnat4!x6.: mo'l !xfed%6*d8"eax
lookuppnat4!x6c: mo'l eax")!x&0ebp1
lookuppnat4!x6f: mo'l !x&0edi1"eax
lookuppnat4!x.$: cmpb ,!x$f"0eax1
lookuppnat4!x.-: Te 4!x## Clookuppnat4!x867
2 ... 3
!an =e have gone do=n the first code)ath J 4bviously not % if there is a >Q?? at
!x&-!0esi1, the testl;Te =ould ta$e us straight to the second code)ath.
(f mdb =ere a bit more friendly about )rinting symbol names instead of an address li$e
!xfed%6*d8 =ithin the code, everything =ould be already clear. 0o =e need an
additional ste)/
7 !xfed%6*d8::B/atis
fed%6*d8 is rootdir4! in genunix]s bss
7 !xfed%6*d8/9
rootdir:
rootdir: !
7 !xfed%6*d8::B/att;pe
fed%6*d8 is fed%6*d84!" 'node6t E
And there =e are % rootdir, the very variable that =e >Q??>ed out deliberately.
7.0olaris;x86 !rashdum) Analysis 1.
9.*.6*bit ,ernel rashd!mp analysis - well ,nown
example
As introduction to crashdum) analysis on 0olaris;x86 6.bit, =e again use deliberate
corru)tion of rootdir. 0ince =e>ve already seen a dum) =here =e =rite >Q?? there,
let>s no= try something different/ !x#$%&-6.8*!abcdef. 2un this to re)roduce/
ec/o Irootdir/U !x#$%&-6.8*!abcdefI G mdb )kB
9.*.1.Pani messages
3he machine )anics similar to this/
3he )anic message consists of the same com)onents that =e already $no= from "2bit
x86 For 01A2!G crashdum)s/
1. 3he )anic string. (t>s a bad tra) again, but a general protection fault, DNP/
panic2cpu!3/t/read[ffffffff8-*ef*!!:
:HK TOHP: t;pe[d 0Dgp Neneral protection1 rp[ffffffffb$ef8bf! addr[feef!#8!
2. 3he register dum) for general6)ur)ose and control register contents. Again, this is
only sho=n Fand only meaningfulG because the reason for the )anic is a :HK TOHP.
As in "2bit mode, the register dum) is a )retty)rint version of the tra)frame, and
the address of that is in found both in the rp[... field and the frame)ointer of
cmntrap01.
155 7.0olaris;x86 !rashdum) Analysis
Illustration 3 ! 1olaris/%&' panic messages on a '*bit kernel
)anicing instruction
bac$trace/
% frame)ointers
% return addresses
% no arguments R
address of saved registers
one stac$)ointer
p$)ic[cp3-]4#"re$d5ffffffff859ef9--1
78 !R8P1 #9pe5d (:gp Be)er$% pr;#ec#i;)) rp5ffffffffb2ef8bf- $ddr5feef-18-
s"1
:gp Be)er$% pr;#ec#i;)
$ddr5-xfeef-18-
pid565A, pc5-xfffffffffe825dbb, sp5-xffffffffb2ef8cd8, ef%$gs5-x1-246
cr-1 8--5--?b*pg,@p,)e,e#,#s,<p,pe+ cr41 6f-*x<<e,fxsr,pge,<ce,p$e,pse+
cr21 feef-18- cr?1 Af-A---- cr81 -
rdi1 12?456A89-$bcdef rsi1 - rdx1 ffffffff859ef9--
rcx1 - r81 ffffffffb2ef8eA8 r91 -
r$x1 - rbx1 12?456A89-$bcdef rbp: ffffffffb2ef8d40
r1-1 8-4Ad28 r111 - r121 ffffffffb2ef8dA-
r1?1 12?456A89-$bcdef r141 ffffffff82-42c4- r151 -
fsb1 ffffffff8------- gsb1 fffffffffec2c4$- ds1 4?
es1 4? fs1 - gs1 -
#rp1 d err1 - rip1 fffffffffe825dbb
cs1 28 rf%1 1-246 rsp1 ffffffffb2ef8cd8
ss1 ?-
ffffffffb2ef8$f- 3)ix1re$%&<;de&e)d+4611 (ffffffffb2ef8c9-, fffffffff)
ffffffffb2ef8be- 3)ix1#r$p+964 ()
ffffffffb2ef8bf- 3)ix1c<)#r$p+11b ()
ffffffffb2ef8d4- 3)ix1<3#ex&e)#er+b ()
ffffffffb2ef8e-- ge)3)ix1%;;>3p)$<e$#+86 ()
ffffffffb2ef8e5- ge)3)ix1cs#$#$#&ge#2p+115 ()
ffffffffb2ef8eb- ge)3)ix1cs#$#$#64&?2+49 ()
ffffffffb2ef8ec- ge)3)ix1s#$#64&?2+22 ()
s9)ci)g fi%e s9s#e<s...
p$)ic[cp3-]4#"re$d5ffffffff859ef9--1
78 !R8P1 #9pe5d (:gp Be)er$% pr;#ec#i;)) rp5ffffffffb2ef8bf- $ddr5feef-18-
s"1
:gp Be)er$% pr;#ec#i;)
$ddr5-xfeef-18-
pid565A, pc5-xfffffffffe825dbb, sp5-xffffffffb2ef8cd8, ef%$gs5-x1-246
cr-1 8--5--?b*pg,@p,)e,e#,#s,<p,pe+ cr41 6f-*x<<e,fxsr,pge,<ce,p$e,pse+
cr21 feef-18- cr?1 Af-A---- cr81 -
rdi1 12?456A89-$bcdef rsi1 - rdx1 ffffffff859ef9--
rcx1 - r81 ffffffffb2ef8eA8 r91 -
r$x1 - rbx1 12?456A89-$bcdef rbp: ffffffffb2ef8d40
r1-1 8-4Ad28 r111 - r121 ffffffffb2ef8dA-
r1?1 12?456A89-$bcdef r141 ffffffff82-42c4- r151 -
fsb1 ffffffff8------- gsb1 fffffffffec2c4$- ds1 4?
es1 4? fs1 - gs1 -
#rp1 d err1 - rip1 fffffffffe825dbb
cs1 28 rf%1 1-246 rsp1 ffffffffb2ef8cd8
ss1 ?-
ffffffffb2ef8$f- 3)ix1re$%&<;de&e)d+4611 (ffffffffb2ef8c9-, fffffffff)
ffffffffb2ef8be- 3)ix1#r$p+964 ()
ffffffffb2ef8bf- 3)ix1c<)#r$p+11b ()
ffffffffb2ef8d4- 3)ix1<3#ex&e)#er+b ()
ffffffffb2ef8e-- ge)3)ix1%;;>3p)$<e$#+86 ()
ffffffffb2ef8e5- ge)3)ix1cs#$#$#&ge#2p+115 ()
ffffffffb2ef8eb- ge)3)ix1cs#$#$#64&?2+49 ()
ffffffffb2ef8ec- ge)3)ix1s#$#64&?2+22 ()
s9)ci)g fi%e s9s#e<s...
As in "2bit mode, =e get additional information about
the )anicing )rocess Fthe shell in this caseG,
a re)rint of the tra) ty)e F['1G
the address of the assembly instruction that caused the bad tra). (t>s )rinted
three times % as pc[..., as value of the rip register, and as symbol name in
the bac$trace, for the frame immediately belo= the tra)frame.
-ut there are several things that are different from "2bit mode/
3he order in =hich the general6)ur)ose registers are )rinted has changed.
3he register )rint starts =ith the si% argument registers, the remaining
general6)ur)ose registers follo=, including the ne= ones r#!...r#- that 6.bit
code can use.
rsp is not )rinted among the general6)ur)ose registers, but only at the end.
(t>s identical to the value )rinted as sp[... 6 and it ma9es sense A
2egisters fsb and gsb are not )resent in a "2bit x86 crashdum).
3he segment registers contain different values than in "2bit mode. (n fact, the
values they have =ould be illegal in "2bit mode 6 fs;gs being >Q??, and the
t=o es;ds having userland F5x." % lo= 2 bits set, ring " segmentG values.
0ee cha)ter " % this is the =ay the 6.bit )rotected mode =or$s. 3he !1*
determines its o)erating mode F6.bit long mode or "2bit com)atibility modeG
based on cs alone and im)licitly assumes flat address s)aces.
". Cinally, =e get a backtrace. 0ince the 0olaris;x86 6.bit $ernel uses the to) end of
the address s)ace, all $ernel addresses there start =ith !xffffff...........
4ne difference to "2bit mode is very noticeable % no arguments in the
bac9trace A
9.*.".$mmediate a!se of the pani : sta,traing
3he first thing =e notice is that it didn>t )anic =ith a )agefault but =ith a DNP
FLgeneral )rotectionLG fault. 3his is, as mentioned in cha)ter ", a )eculiar side effect of
the A#76. virtual address s)ace hole 6 addresses bet=een !x!!!!.fffffffffff and
!xffff8!!!!!!!!!!! are Lnon6canonicalL and create DNP faults on access 6 not
)agefaults. (t still means that the address is invalid.
3he )anic message )rint an addr[... field/
:HK TOHP: t;pe[d 0Dgp Neneral protection1 rp[ffffffffb$ef8bf! addr[feef!#8!
-ut this is nonsense for a DNP tra) % because, as =ith the "2bit version of this crash,
the $ernel sim)ly )rints the contents of the )agefault address register cr$, and that,
as the name im)licates, contains the address of the last )agefault. -ut here no
)agefault ha))ened % so cr$ is stale, and =e better forget about =hat addr[... tells
us. (f =e really =ant to $no= the faulting address for this, let>s loo$ at the )anicing
instruction/
2 ... 3
pid[6-." pc[!xfffffffffe8$-dbb" sp[!xffffffffb$ef8cd8" eflags[!x#!$&6
2 ... 3
rdi: #$%&-6.8*!abcdef rsi: ! rdx: ffffffff8-*ef*!!
2 ... 3
trp: d err: ! rip: fffffffffe8$-dbb
2 ... 3
7 fffffffffe8$-dbb/i
mutex6enter4!xb: lock cmpxc/g+ rdx"0rdi1
7.0olaris;x86 !rashdum) Analysis 151
0o the DNP fault occurred attem)ting to )erform a 6.bit atomic com)are6and6s=a) of
rdx =ith the contents of the memory location rdi )oints to. And that, as =e see
from the )anic message, contains the value !x#$%&-6.8*!abcdef that =as used to
corru)t rootdir.
Ho= did =e get there J <et>s start =ith mutex6enter01 again/
7 mutex6enter::dis
mutex6enter: mo'+ gs:!x#8"rdx
mutex6enter4*: xorl eax"eax
mutex6enter4!xb: lock cmpxc/g+ rdx"0rdi1
mutex6enter4!x#!: Tne 4!xe#b! Cmutex6'ector6enter7
mutex6enter4!x#6: ret
3he first instruction loo$s sur)rising, given that the register dum) from the )anic
message claimed gs =as >Q??. -ut actually, this is Bust curt/read, x86 6.bit style. (n
6.bit mode, there>s a register, gsb, =hich directly holds the segment base address to
be used =hen gs references are made. <oo$ at E0gsb4!x#81 and you>ll find/
panic2cpu!3/t/read[ffffffff8-*ef*!!:
2 ... 3
fsb: ffffffff8!!!!!!! gsb: fffffffffec$c&a! ds: &%
2 ... 3
7 !xfffffffffec$c&a!4!x#8/8 G ::B/atis
7 fffffffffec$c&a!4!x#8/8 G ::B/atis
ffffffff8-*ef*!! is ffffffff8-*ef*!!4!" allocated as a t/read structure
7 panic6t/read/8
panic6t/read:
panic6t/read: ffffffff8-*ef*!!
3his is the same code =e $no= from "2bit x86, though =e no longer need to loo$ into
the descri)tor tables to find out =hat gs really )oints to. gsb directly has the )ointer
for us
mutex6enter01 directly exchanges curthread =ith its first argument, )assed in rdi.
Cinding the call se9uence that lead to the )anic is sim)ler on x86 in 6.bit than in "2bit
mode % because the re)orted stac$)ointer is correct. rsp;sp[... is the value of the
kernel stackpointer #alue before the panic A
3his can be crosschec$ed in t=o =ays/
Cirst, because the last thing that =rote a value to the stac$ =as the call to
mutex6enter01, =e =ill find a return address at the location rsp from the saved
registers )oints to/
2 ... 3
pid[6-." pc[!xfffffffffe8$-dbb" sp[!xffffffffb$ef8cd8" eflags[!x#!$&6
2 ... 3
cs: $8 rfl: #!$&6 rsp: ffffffffb$ef8cd8
2 ... 3
7 ffffffffb$ef8cd8/nap
!xffffffffb$ef8cd8:
!xffffffffb$ef8cd8: lookuppnat4!xa8
7 lookuppnat4!xa8::dis
2 ... 3
lookuppnat4!xa!: mo'+ rbx"rdi
lookuppnat4!xa%: call )!xe-8e% Cmutex6enter7
lookuppnat4!xa8: incl !xc0rbx1
2 ... 3
0econd, =hen loo$ing at the '*bit trapframe, =e find that rsp is only )resent in the
bottom hard=are )art, and )oints after the end of that % and therefore must have been
152 7.0olaris;x86 !rashdum) Analysis
=ritten by the !1* before dis)atching the tra) handler/
ra= data on the stac9 saved registers C struct regs
7 ffffffffb$ef8bf!"&!/nap
!xffffffffb$ef8bf!:
!xffffffffb$ef8bf!: !x#$%&-6.8*!abcdef
!xffffffffb$ef8bf8: !
!xffffffffb$ef8c!!: !xffffffff8-*ef*!!
!xffffffffb$ef8c!8: !
!xffffffffb$ef8c#!: !xffffffffb$ef8e.8
!xffffffffb$ef8c#8: !
!xffffffffb$ef8c$!: !
!xffffffffb$ef8c$8: !x#$%&-6.8*!abcdef
!xffffffffb$ef8c%!: 0xffffffffb2ef8d40
!xffffffffb$ef8c%8: !x8!&.d$8
!xffffffffb$ef8c&!: !
!xffffffffb$ef8c&8: !xffffffffb$ef8d.!
!xffffffffb$ef8c-!: !x#$%&-6.8*!abcdef
!xffffffffb$ef8c-8: !xffffffff8$!&$c&!
!xffffffffb$ef8c6!: !
!xffffffffb$ef8c68: !xffffffff8!!!!!!!
!xffffffffb$ef8c.!: cpus
!xffffffffb$ef8c.8: !x&%
!xffffffffb$ef8c8!: !x&%
!xffffffffb$ef8c88: !
!xffffffffb$ef8c*!: !
!xffffffffb$ef8c*8: !xd
!xffffffffb$ef8ca!: !
!xffffffffb$ef8ca8: mutex6enter4!xb
!xffffffffb$ef8cb!: !x$8
!xffffffffb$ef8cb8: !x#!$&6
!xffffffffb$ef8cc!: !xffffffffb$ef8cd8
!xffffffffb$ef8cc8: !x%!
!xffffffffb$ef8cd!: !xffffffffb$ef8cf!
!xffffffffb$ef8cd8: lookuppnat4!xa8
7 ffffffffb$ef8bf!::print )a Istruct regsI
V
ffffffffb$ef8bf! r6rdi [ !x#$%&-6.8*!abcdef
ffffffffb$ef8bf8 r6rsi [ !
ffffffffb$ef8c!! r6rdx [ !xffffffff8-*ef*!!
ffffffffb$ef8c!8 r6rcx [ !
ffffffffb$ef8c#! r6r8 [ !xffffffffb$ef8e.8
ffffffffb$ef8c#8 r6r* [ !
ffffffffb$ef8c$! r6rax [ !
ffffffffb$ef8c$8 r6rbx [ !x#$%&-6.8*!abcdef
ffffffffb$ef8c%! r6rbp [ 0xffffffffb2ef8d40
ffffffffb$ef8c%8 r6r#! [ !x8!&.d$8
ffffffffb$ef8c&! r6r## [ !
ffffffffb$ef8c&8 r6r#$ [ !xffffffffb$ef8d.!
ffffffffb$ef8c-! r6r#% [ !x#$%&-6.8*!abcdef
ffffffffb$ef8c-8 r6r#& [ !xffffffff8$!&$c&!
ffffffffb$ef8c6! r6r#- [ !
ffffffffb$ef8c68 r6fsbase [ !xffffffff8!!!!!!!
ffffffffb$ef8c.! r6gsbase [ !xfffffffffec$c&a!
ffffffffb$ef8c.8 r6ds [ !x&%
ffffffffb$ef8c8! r6es [ !x&%
ffffffffb$ef8c88 r6fs [ !
ffffffffb$ef8c*! r6gs [ !
ffffffffb$ef8c*8 r6trapno [ !xd
ffffffffb$ef8ca! r6err [ !
ffffffffb$ef8ca8 r6rip [ !xfffffffffe8$-dbb
ffffffffb$ef8cb! r6cs [ !x$8
ffffffffb$ef8cb8 r6rfl [ !x#!$&6
ffffffffb$ef8cc! r6rsp [ !xffffffffb$ef8cd8
ffffffffb$ef8cc8 r6ss [ !x%!
X
3he only thing in this stac$ that seems odd on first glance is the value bet=een the end
of the tra)frame and the saved rsp/
!xffffffffb$ef8cc8: !x%!
!xffffffffb$ef8cd!: !xffffffffb$ef8cf!
!xffffffffb$ef8cd8: lookuppnat4!xa8
-ut this is, see cha)ter ", normal behaviour for 6.bit gates % they align the stac$ at a
multi)le of 16 -ytes. 0o this in6bet=een value has no meaning % it>s )adding and Bust
old, )re6tra) stale information still in this memory location.
0o the big "2bit x86 )roblem ?ho= do ( find the $ernel stac$)ointer at the time of the
)anic@ is trivial on 6.bit x86/ Ee can trust rsp from the )anic register dum).
0tac$ bac$tracing in the 0olaris;x86 6.bit kernel =or$s the same =ay as before/
Output of $ manually follo=ing framepointers
7 ,C
ffffffffb$ef8d&! mutex6enter4!xb
ffffffffb$ef8e!! lookupnameat4!x86
ffffffffb$ef8e-! cstatat6get'p4!x##-
ffffffffb$ef8eb! cstatat6&6%$4!x&*
ffffffffb$ef8ec! stat6&6%$4!x$$
Crbp[8WCrip[pWCrbp/n8p
ffffffffb$ef8d&!
mutex6enter4!xb
ffffffffb$ef8d&!:
ffffffffb$ef8e!! lookupnameat4!x86
7 E./n8p
ffffffffb$ef8e!!:
ffffffffb$ef8e-! cstatat6get'p4!x##-
7 E./n8p
ffffffffb$ef8e-!:
ffffffffb$ef8eb! cstatat6&6%$4!x&*
7 E./n8p
ffffffffb$ef8eb!:
ffffffffb$ef8ec! stat6&6%$4!x$$
7.0olaris;x86 !rashdum) Analysis 15"
Output of $ manually follo=ing framepointers
ffffffffb$ef8f$! s;s6s;scall%$4!xd!
!!!!!!!!!8!.6c*! #
7 E./n8p
ffffffffb$ef8ec!:
ffffffffb$ef8f$! s;s6s;scall%$4!xd!
7 E./n8p
!xffffffffb$ef8f$!:
8!.6c*! #
Ehen loo$ing at the ra= stac$ starting =ith the tra) frame, =e find the same lin$age/
2 ... 3
:HK TOHP: t;pe[d 0Dgp Neneral protection1 rp[ffffffffb$ef8bf! addr[feef!#8!
2 ... 3
7 ffffffffb$ef8bf!"#!!/nap
!xffffffffb$ef8bf!:
!xffffffffb$ef8bf!: !x#$%&-6.8*!abcdef
!xffffffffb$ef8bf8: !
!xffffffffb$ef8c!!: !xffffffff8-*ef*!!
!xffffffffb$ef8c!8: !
!xffffffffb$ef8c#!: !xffffffffb$ef8e.8
!xffffffffb$ef8c#8: !
!xffffffffb$ef8c$!: !
!xffffffffb$ef8c$8: !x#$%&-6.8*!abcdef
!xffffffffb$ef8c%!: 0xffffffffb2ef8d40
!xffffffffb$ef8c%8: !x8!&.d$8
!xffffffffb$ef8c&!: !
!xffffffffb$ef8c&8: !xffffffffb$ef8d.!
!xffffffffb$ef8c-!: !x#$%&-6.8*!abcdef
!xffffffffb$ef8c-8: !xffffffff8$!&$c&!
!xffffffffb$ef8c6!: !
!xffffffffb$ef8c68: !xffffffff8!!!!!!!
!xffffffffb$ef8c.!: cpus
!xffffffffb$ef8c.8: !x&%
!xffffffffb$ef8c8!: !x&%
!xffffffffb$ef8c88: !
!xffffffffb$ef8c*!: !
!xffffffffb$ef8c*8: !xd trap number
!xffffffffb$ef8ca!: !
!xffffffffb$ef8ca8: mutex6enter4!xb
!xffffffffb$ef8cb!: !x$8
!xffffffffb$ef8cb8: !x#!$&6
!xffffffffb$ef8cc!: !xffffffffb$ef8cd8
!xffffffffb$ef8cc8: !x%!
!xffffffffb$ef8cd!: !xffffffffb$ef8cf! padding I pre!trap aligned rsp
!xffffffffb$ef8cd8: lookuppnat4!xa8 stack end at time of trap
2 ... 3
0xffffffffb2ef8d40: 0xffffffffb2ef8e00
!xffffffffb$ef8d&8: lookupnameat4!x86
2 ... 3
0xffffffffb2ef8e00: 0xffffffffb2ef8e50
!xffffffffb$ef8e!8: cstatat6get'p4!x##-
2 ... 3
0xffffffffb2ef8e50: 0xffffffffb2ef8eb0
!xffffffffb$ef8e-8: cstatat6&6%$4!x&*
2 ... 3
0xffffffffb2ef8eb0: 0xffffffffb2ef8ec0
!xffffffffb$ef8eb8: stat6&6%$4!x$$
0xffffffffb2ef8ec0: 0xffffffffb2ef8f20
!xffffffffb$ef8ec8: s;s6s;scall%$4!xd!
2 ... 3
15. 7.0olaris;x86 !rashdum) Analysis
3
r
a
)

C
r
a
m
e
0
a
v
e
d

r
e
g
i
s
t
e
r
s
,
=
r
i
t
t
e
n

b
y

c
<
)
#
r
$
p
(
)
HE )art of
tra)frame
saved by the !1*
before calling gate
0xffffffffb2ef8f20: !x8!.6c*!
!xffffffffb$ef8f$8: #
!xffffffffb$ef8f%!: !xdf
!xffffffffb$ef8f%8: !xfef*f-a.
!xffffffffb$ef8f&!: !x8!.%%!c
!xffffffffb$ef8f&8: !
!xffffffffb$ef8f-!: !xd.
!xffffffffb$ef8f-8: #
!xffffffffb$ef8f6!: !x8!&.dd&
!xffffffffb$ef8f68: !x8!&.e.c
!xffffffffb$ef8f.!: !x$*6
!xffffffffb$ef8f.8: !x&$#%8.!#
!xffffffffb$ef8f8!: !
!xffffffffb$ef8f88: !xffffffff8-.d6cc!
!xffffffffb$ef8f*!: !xffffffff8-*ef*!!
!xffffffffb$ef8f*8: !xffffffff8!!!!!!!
!xffffffffb$ef8fa!: !xfeef$!!!
!xffffffffb$ef8fa8: !x&%
!xffffffffb$ef8fb!: !x&%
!xffffffffb$ef8fb8: !
!xffffffffb$ef8fc!: !x#c%
!xffffffffb$ef8fc8: !xe
!xffffffffb$ef8fd!: .
!xffffffffb$ef8fd8: !xfef*f-a.
!xffffffffb$ef8fe!: !x%b
!xffffffffb$ef8fe8: !x$!$
!xffffffffb$ef8ff!: !x8!&.d$8
!xffffffffb$ef8ff8: !x&%
mdb: failed to read data from target: no mapping for address
!xffffffffb$ef*!!!:
7.0olaris;x86 !rashdum) Analysis 155
0
y
s
t
e
m

!
a
l
l
C
r
a
m
e
9.*.'.Finding f!ntion arg!ments
(t has been sho=n that in 6.bit mode, mdb )rints no arguments in bac$traces. 3his of
course is due to the fact that the x86 6.bit A-( uses registers rdi, rsi, rdx, rcx,
r8 and r* Fin that orderG to )ass the first six FintegerG arguments and only resorts to
using the stac$ if there are more. (n a call trace the argument registers are
over=ritten each time another function is called, and so =e only can reconstruct their
values at the time of a :HK TOHP, using the contents of the tra)frame.
Ehich is =hy mdb in 6.bit x86 doesn>t give arguments in stac$traces. All traces loo$
li$e this/
7 ,C
ffffffffb$ef8d&! mutex6enter4!xb01
ffffffffb$ef8e!! lookupnameat4!x8601
ffffffffb$ef8e-! cstatat6get'p4!x##-01
ffffffffb$ef8eb! cstatat6&6%$4!x&*01
ffffffffb$ef8ec! stat6&6%$4!x$$01
ffffffffb$ef8f$! s;s6s;scall%$4!xd!01
!!!!!!!!!8!.6c*! #01
7 Epanic6t/read::findstack
stack pointer for t/read ffffffff8-*ef*!!: ffffffffb$ef8c%!
ffffffffb$ef8d&! !x8!&.d$801
ffffffffb$ef8e!! lookupnameat4!x8601
ffffffffb$ef8e-! cstatat6get'p4!x##-01
ffffffffb$ef8eb! cstatat6&6%$4!x&*01
ffffffffb$ef8ec! stat6&6%$4!x$$01
ffffffffb$ef8f$! s;s6s;scall%$4!xd!01
!!!!!!!!!8!.6c*! #01
i.e. no arguments.
Ho= can =e overcome this )roblem J
0im)lest solution at this time is to use act.so from the !3Eact )ac$age. 3his, as )art
of the 5utomated 0rash +ool utility )ac$age is a loadable mdb module, =hich )rovides
additional dcmds for mdb. Among these is an enhanced stac$ tracer, in the mdb dcmd
::act6t/read/
7 ::load /opt/CTEact/mdb/-.#!/amd6&/act.so
7 ::dcmds J grep aact
act ) Hutomatic Coredump Tool 2)(Ou3 2)s Cdir73
act6c/eck6bio ) c/eck for t/reads blocked in bioBait
act6c/eck6getblk ) c/eck for t/reads blocked in getblk
act6c/eck6mutex ) c/eck for t/reads blocked on mutex]s
act6c/eck6rBlock ) c/eck for t/reads blocked on rBlock]s
act6dis6cpus ) print dispatc/er +ueues
act6module6name ) print name of module
act6moutput ) print arguments
act6msgbuf ) print console messages
act6procs ) print number of acti'e processes
act6sunsol'e ) print sunsol'e string
act6s;stem ) print contenets of /etc/s;stem
act6t/read ) print t/read 2)PCf@nt3
act6t/read6summar; ) count number of t/reads
act6utsname ) act do utsname
7 Epanic6t/read::act6t/read
EEE
process id 6-. is )s/" parent process is $.!
156 7.0olaris;x86 !rashdum) Analysis
uid is !" gid is !
t/read addr ffffffff8-*ef*!!" proc addr ffffffff8$!&$c&!"
lBp addr ffffffff8-.d6cc!
T/read bound to cpu id !
t6state is !x& ) TS6<>PO<C
Sc/eduling info:
t6pri is !x%b" t6epri is !" t6cid is !x#
sc/eduling class is: TS
t6disp6time: is !x$-a%eb" !t$&66.*-
last sBitc/ed: & secs ago" # sec before panic on cpu !
t6stk ffffffffb$ef8f$!
stack trace is:
unix: panics;s4!x6e 0!xffffffffb$ef8*a!"'panic4!x#.*"panic6stack4!x#f$!"
!xfec$c&a!1
unix: 'panic4!x#.* 01
unix: fffffffffe8%-a$$ 01
unix: panic 0!xfffffffffe8.b!d81
unix: fffffffffe8#b6!. 01
unix: die 05"5"!xfeef!#8!"!1
unix: trap4!x*6& 0!xffffffffb$ef8bf!"!xfeef!#8!"!1
TOHP @OHME: T6NP@?T general protection fault
rdi ! rsio !
rdx !x8-*ef*!! rcx !
r8 !xb$ef8e.8 r* !
rax ! rbx !x*!abcdef
rbp !xb$ef8d&! r#! !x8!&.d$8
r## ! r#$ !xb$ef8d.!
r#% !x*!abcdef r#& !x8$!&$c&!
r#- ! fsb !x8!!!!!!!
gsb !xfec$c&a! ds !x&%
es !x&% fs !
gs ! trp !xd
err ! rip !xfe8$-dbb
cs !x$8 rfl !x#!$&6
rsp !xb$ef8cd8 ss !x%!
unix: mutex6enterunix: mutex6enter4!xb 01
genunix: lookuppnat 05"5"#"!"!xffffffffb$ef8e.8"51
genunix: lookupnameat4!x86 0!x8!.6c*!"!x#$%&-6.8*!abcdef"#"!"!xffffffffb$ef8e.8"
!1
genunix: cstatat6get'p4!x##- 0!xffd#*--%"!x8!.6c*!"#"#"!xffffffffb$ef8e.8"
!xffffffffb$ef8e8!1
genunix: cstatat6&6%$4!x&* 0!xffd#*--%"!x8!.6c*!"#"!x8!&.d&!"5"!x#!1
genunix: stat6&6%$4!x$$ 0!xb$ef8f$!"!xfe8!##$!1
unix: s;s6s;scall%$4!xd! 01
act isn>t )erfect and still getting further enhancements for x86;6.bit. Ee can see, for
exam)le, that the version of act used here doesn>t )rint the contents of the tra) frame
correctly % the u))er "2bits of the 6.bit registers are missing. -ut there are
arguments in the stac$traces % )recisely =hat =e =ant to see A
::act6t/read can be used instead of mdb>s builtin ::findstack in order to get
stac$traces =ith arguments for a given $ernel thread address. (t does not, at this time,
re)lace ,C yet. 3his is another reason for us % a)art from curiosity of course % =hy =e
should find out ho= arguments can be reconstructed from stac$traces.
7.0olaris;x86 !rashdum) Analysis 157
1assing arguments in registers, es)ecially if these are global li$e on A#76., means
that over the lifetime of a function, es)ecially if that in itself is ma$ing more function
calls, the original contents of the argument registers =ill be over=ritten % =ith
variables from the =or$ing set, or =ith ne= arguments for functions to be called.
2egister reuse is the common case on A#76.. *nli$e e.g. 01A2!, =here arguments
are also )assed in registers but the =indo=ing mechanism )rovides every function
=ith an independent set of argument registers, A#76. uses the same set of argument
registers all the time.
Ehich sho=s the =ay out of the )roblem. -efore trying on the crashdum), let>s
investigate the follo=ing ! sourcecode and the binary created from it/
extern int somefunc0int a#" int a$" int a%" int a&" int a-" int a61W
extern 'oid ot/erfunc0int b#" int b$" int b%" int b&" int b-" int b6" int b.1W
int call6tBo6funcs0int a" int b" int c" int d" int e" int f1
V
int localW
local [ somefunc0#" $" %" &" -" 61W
ot/erfunc0a" b" c" d" e" f" local1W
return 0local1W
X
3his creates a situation that is common for ! sourcecode % arguments of a function are
needed during the entire lifetime of that function, no matter ho= many other functions
=ere called in6bet=een. 'iven the A-(, the conse9uences for the generated code are
clear/ A function that needs its arguments even after ma$ing another function call by
itself =ill have to store them in a save )lace % and that>s its o=n stac$frame. A#76.
code therefore =ill create hidden locals in its stac$frame to stuff the arguments in,
similar to "2bit x86 code that )uts the nonvolatile registers to the stac$. 3he binary
code created from the above exam)le sho=s this % red instructions move arguments
into;outof the stac$ res). the nonvolatile registers/
call6tBo6funcs: pus/+ rbp
call6tBo6funcs4!x#: mo'+ rsp"rbp
call6tBo6funcs4!x&: sub+ ,!x&!"rsp
call6tBo6funcs4!x8: mo'+ r#$")!x$!0rbp1
call6tBo6funcs4!xc: mo'+ r#%")!x#80rbp1
call6tBo6funcs4!x#!: mo'l r*d"r#$d
call6tBo6funcs4!x#%: mo'+ r#&")!x#!0rbp1
call6tBo6funcs4!x#.: mo'+ r#-")!x80rbp1
call6tBo6funcs4!x#b: mo'l ecx"r#&d
call6tBo6funcs4!x#e: mo'l edi")!x$c0rbp1
call6tBo6funcs4!x$#: mo'l esi")!x%!0rbp1
call6tBo6funcs4!x$&: mo'l edx"r#-d
call6tBo6funcs4!x$.: mo'l r8d"r#%d
call6tBo6funcs4!x$a: mo'l ,!x6"r*d
call6tBo6funcs4!x%!: mo'l ,!x-"r8d
call6tBo6funcs4!x%6: mo'l ,!x&"ecx
call6tBo6funcs4!x%b: mo'l ,!x%"edx
call6tBo6funcs4!x&!: mo'l ,!x$"esi
call6tBo6funcs4!x&-: mo'l ,!x#"edi
call6tBo6funcs4!x&a: mo'+ rbx")!x$80rbp1
call6tBo6funcs4!x&e: call 4!x- Ccall6tBo6funcs4!x-%7
call6tBo6funcs4!x-%: mo'l )!x%!0rbp1"esi
call6tBo6funcs4!x-6: mo'l )!x$c0rbp1"edi
call6tBo6funcs4!x-*: mo'l eax"ebx
call6tBo6funcs4!x-b: mo'l r#$d"r*d
call6tBo6funcs4!x-e: mo'l r#%d"r8d
158 7.0olaris;x86 !rashdum) Analysis
call6tBo6funcs4!x6#: mo'l r#&d"ecx
call6tBo6funcs4!x6&: mo'l r#-d"edx
call6tBo6funcs4!x6.: mo'l eax"0rsp1
call6tBo6funcs4!x6a: call 4!x- Ccall6tBo6funcs4!x6f7
call6tBo6funcs4!x6f: mo'l ebx"eax
call6tBo6funcs4!x.#: mo'+ )!x$!0rbp1"r#$
call6tBo6funcs4!x.-: mo'+ )!x$80rbp1"rbx
call6tBo6funcs4!x.*: mo'+ )!x#80rbp1"r#%
call6tBo6funcs4!x.d: mo'+ )!x#!0rbp1"r#&
call6tBo6funcs4!x8#: mo'+ )!x80rbp1"r#-
call6tBo6funcs4!x8-: lea'e
call6tBo6funcs4!x86: ret
3his behaviour of com)iler6generated code of course means that =e>ll often be able to
find arguments for functions in 6.bit x86 bac$traces if =e use the follo=ing strategy/
1. 7isassemble the function you =ant to find the arguments for, and determine
=hether it moves the argument registers into the stac$, i.e. into locals )...0rbp1.
(f it does, you>ve found them.
2. (f not, see =hether it moves argument registers into nonvolatile registers, i.e. from
registers rdi;rsi;rdx;rcx;r8;r* to rbx;r#$;r#%;r#&;r#-.
(f it does, disassemble the ne%t function in the call trace. 3his =ill )robably, as )art
of its function )rologue, save Fsome or all ofG the nonvolatile registers onto the
stac$. 7o that recursively until all nonvolatile regs are on the stac$ % or until you
find a tra)frame and get the remaining register contents from there.
". (f the function you started out =ith did neither save its argument registers to the
stac$ nor )ut them into nonvolatile registers, go bac$ to the pre#ious function Fi.e.
the callerG in the call trace and determine =here the arguments to your function of
interest =ere ta$en from.
3his )rocess, as indicated by the A!3 out)ut, can be automated to a certain extent.
3here>s no guarantee that this succeeds, of course % A!3, if it cannot determine =here
an argument =ent, =ill )rint 5 instead/
2 ... 3
genunix: lookuppnat 05"5"#"!"!xffffffffb$ef8e.8"51
2 ... 3
(n the case sho=n, act failed to find the first t=o and the sixth arguments to
lookuppnat01. <et>s try the )rocedure manually and see =hether =e can do better/
7 lookuppnat::dis
lookuppnat: pus/+ rbp
lookuppnat4#: mo'+ rsp"rbp
lookuppnat4&: sub+ ,!x6!"rsp
lookuppnat48: mo'+ r#$")!x$!0rbp1
lookuppnat4!xc: mo'+ r#-")!x80rbp1
lookuppnat4!x#!: mo'+ rdi"r#$
lookuppnat4!x#%: mo'+ rbx")!x$80rbp1
lookuppnat4!x#.: mo'+ r#%")!x#80rbp1
lookuppnat4!x#b: mo'+ r*"r#-
lookuppnat4!x#e: mo'+ r#&")!x#!0rbp1
lookuppnat4!x$$: mo'+ rsi")!x%!0rbp1
lookuppnat4!x$6: mo'l edx")!x%&0rbp1
lookuppnat4!x$*: mo'+ rcx")!x&!0rbp1
lookuppnat4!x$d: mo'+ r8")!x&80rbp1
lookuppnat4!x%#: mo'+ gs:!x#8"rax
lookuppnat4!x%a: cmp+ ,!x!"!x#!0rdi1
lookuppnat4!x%f: mo'+ !x#680rax1"r#&
lookuppnat4!x&6: mo'l ,!x$"eax
7.0olaris;x86 !rashdum) Analysis 15
lookuppnat4!x&b: Te 4!xae Clookuppnat4!xf*7
lookuppnat4!x-#: mo'+ !x#!0r#&1"rdi
lookuppnat4!x--: call )!xe-8*- Cmutex6enter7
Hes % =e obviously can. All six arguments are accounted for/
rdi F1
st
argG is )ut into nonvolatile register r#$. !rosschec$ing that this is never
again over=ritten exce)t in the function e)ilogue/
2 ... 3
lookuppnat48: mo'+ r#$")!x$!0rbp1
2 ... 3
7 lookuppnat::dis J grep ]r#$,]
lookuppnat4!x#!: mo'+ rdi"r#$
lookuppnat4!xfd: mo'+ )!x$!0rbp1"r#$
0ince the next thing after lookuppnat01 =as the )anic in mutex6enter01, =e $no=
that the value of r#$ in the )anic registers still has the value =e>re loo$ing for/
7 ::msgbuf
2 ... 3
r#!: 8!&.d$8 r##: ! r#$: ffffffffb$ef8d.!
2 ... 3
rsi F2
nd
argG is )ut into )!x%!0rbp1. Again, using the frame)ointer for
lookuppnat01 that>s in the )anic registers, =e can locate the argument/
2 ... 3
rax: ! rbx: #$%&-6.8*!abcdef rbp@ ffffffffb2ef8d40
2 ... 3
7 ffffffffb2ef8d40)%!/8
!xffffffffb$ef8d#!: !
edx F"
rd
arg, obviously a "2bit intG is )ut into )!x%&0rbp1/
7 ffffffffb2ef8d40)%&/9
!xffffffffb$ef8d!c: #
rcx F.
th
argG is )ut into 65x.5FYrb)G/
7 ffffffffb2ef8d40)&!/8
!xffffffffb$ef8d!!: !
r8 F5
th
argG goes to )!x&80rbp1/
7 ffffffffb2ef8d40)&!/8
!xffffffffb$ef8cf8: ffffffffb$ef8e.8
r* F6
th
argG is )ut into nonvolatile register r#-. Again, =e need to chec$ that the
function never reinitialiKes r#- =ith something else before =e can claim that the
value of r#- from the tra) frame still has it/
2 ... 3
lookuppnat4!xc: mo'+ r#-")!x80rbp1
2 ... 3
7 lookuppnat::dis J grep ]r#-,]
lookuppnat4!x#b: mo'+ r*"r#-
lookuppnat4!x*&: test+ r#-"r#-
lookuppnat4!x#!*: mo'+ )!x80rbp1"r#-
7 ::msgbuf
2 ... 3
r#%: #$%&-6.8*!abcdef r#&: ffffffff8$!&$c&! r#-: !
2 ... 3
3his strategy is generic and can be a))lied to all stac$traces on A#76..
165 7.0olaris;x86 !rashdum) Analysis
9.*.*.Pieing it all together
&o= that =e $no= ho= bac$tracing in the 0olaris;x86 6.bit $ernel is done and ho=
arguments to functions can be retrieved in s)ite of the use of registers for argument
)assing, =e>re ready to )ut the )ieces together and determine ho= over=riting
rootdir =ith !x#$%&-6.8*!abcdef could cause the )anic =e>ve got.
mutex6enter01 )aniced because !x#$%&-6.8*!abcdef Fan invalid, noncanonical
virtual addressG =as )assed to it as argument/
7 mutex6enter::dis
mutex6enter: mo'+ gs:!x#8"rdx
mutex6enter4*: xorl eax"eax
mutex6enter4!xb: lock cmpxc/g+ rdx"0rdi1
2 ... 3
7 ::msgbuf
2 ... 3
rdi: #$%&-6.8*!abcdef rsi: ! rdx: ffffffff8-*ef*!!
2 ... 3
0ince mutex6enter01 itself doesn>t )ush anything to the stac$, the stac$)ointer at the
time the -A7 32A1 occurred still must )oint to the return address, giving us the caller
of mutex6enter01. (t>s an A#76. crashdum), so rsp from the HE )art of the tra)
frame is correct and =e can directly use that/
2 ... 3
pid[6-." pc[!xfffffffffe8$-dbb" sp[!xffffffffb$ef8cd8" eflags[!x#!$&6
2 ... 3
cs: $8 rfl: #!$&6 rsp: ffffffffb$ef8cd8
2 ... 3
7 ffffffffb$ef8cd8/p
!xffffffffb$ef8cd8: lookuppnat4!xa8
7 Effffffffb$ef8cd8::dis
2 ... 3
lookuppnat4!xa!: mo'+ rbx"rdi
lookuppnat4!xa%: call )!xe-8e% Cmutex6enter7
lookuppnat4!xa8: incl !xc0rbx1
2 ... 3
3his tells us lookuppnat4!xa% =as the location =here mutexSenterFG =as called from.
Ee need to figure out =here the argument FrdiG =as ta$en from. 3he sourcecode for
lookuppnat01 is generic !, and therefore =e can ex)ect the 6.bit code to have an
identical flo= as the "2bit code. (n fact =e find code so similar to the "2bit version that
it>s =orth sho=ing the t=o side6by6side/
!"bit code -7bit code
lookuppnat:
2 ... 3
4!x..: mo'l !x#c0ebp1"ebx
4!x.a: testl ebx"ebx
4!x.c: Tne Clookuppnat4!x8*7
4!x.e: mo'l !x&&c0esi1"ebx
4!x8&: Tmp Clookuppnat4!x8*7
4!x86: mo'l )!x&0ebp1"ebx
4!x8*: pshl !ebx
4!x8a: call Cmutex6enter7
4!x8f: addl ,!x&"esp
lookuppnat:
2 ... 3
4!x#b: mo'+ r*"r#-
2 ... 3
4!x8c: mo'+ r#%"rbx
4!x8f: cmpb ,!x$f"0rax1
4!x*$: Te Clookuppnat4!xa!7
4!x*&: test+ r#-"r#-
4!x*.: mo'+ r#-"rbx
4!x*a: Te Clookuppnat4!x#&&7
4!xa!: mo'+ rbx"!rdi
4!xa%: call Cmutex6enter7
2 ... 3
4!x#&&:mo'+ !x6$80r#&1"rbx
7.0olaris;x86 !rashdum) Analysis 161
!"bit code -7bit code
4!x#&b:Tmp Clookuppnat4!xa!7
3he 6.bit code, as sho=n earlier, )uts its 6
th
argument into r#- for )ermanent
availability. (f that>s non6>Q??, it>s being used as argument for mutex6enter01. -ut
then the tra)frame already has sho=n that it =as >Q??, so as in "2bit the invalid value
cannot have come from there. !an it have come from !x6$80r#&1 J 'etting r#&
from the tra)frame and chec$ing this memory location tells us/
2 ... 3
r#%: #$%&-6.8*!abcdef r#&: ffffffff8$!&$c&! r#-: !
2 ... 3
7 ffffffff8$!&$c&!46$8/8
!xffffffff8$!&%$68: ffffffff8#c$.c&!
0o this =asn>t it either. 2emains r#% Fa local variable, as in "2bitG. Ehich in the )anic
registers holds the cul)rit, !x#$%&-6.8*!abcdef. 0o chec$ lookuppnat01 for =here it
initialiKes r#% from/
7 lookuppnat::dis J grep ]r#%,]
lookuppnat4!x-a: mo'+ !x6%!0r#&1"r#%
lookuppnat4!x6#: test+ r#%"r#%
lookuppnat4!x6a: cmp+ !x-6$8cf0rip1"r#%
lookuppnat4!x#!#: mo'+ )!x#80rbp1"r#%
lookuppnat4!x#%8: mo'+ !x-6$8!#0rip1"r#%
3he indirect memory reference !x6%!0r#&1 and the local variable )!x#80rbp1 are
sim)le to test, and they do not contain !x#$%&-6.8*!abcdef/
2 ... 3
rax: ! rbx: #$%&-6.8*!abcdef rbp: ffffffffb$ef8d&!
2 ... 3
r#%: #$%&-6.8*!abcdef r#&: ffffffff8$!&$c&! r#-: !
7 ffffffff8$!&$c&!46%!/8
!xffffffff8$!&%$.!: !
7 ffffffffb2ef8d40)#8/8
!xffffffffb$ef8d$8: !
0o these cannot have been it either.
3he only thing that remains is the rip6relative location !x-6$8!#0rip1. (t>d be nice
if mdb =ould resolve this for us Fit has the ca)ability, since it does resolve call
targets, and these are also rip6relative ...G, but as it obviously doesn>t do that FyetG
let>s =or$ on it ourselves again. 3he code is/
7 lookuppnat4!x#%8::dis
2 ... 3
lookuppnat4!x#%8: mo'+ !x-6$8!#0rip1"r#%
lookuppnat4!x#%f: Tmp )!xb8 Clookuppnat4!x8.7
Ehat value is used for rip J 3he ans=er is/ 3he same that the call instruction =ould
use to )ut onto the stac$ as the return address. (n other =ords/ (n an instruction that
ma$es a rip6relative reference, rip =ill contain the address of the follo$ing
instruction. !leartext/ lookuppnat4!x#%f in the case above. 2esolve the rip6relative
address/
7 lookuppnat4!x#%f4!x-6$8!#/8
rootdir:
rootdir: #$%&-6.8*!abcdef
&o= there =e are. 3=isted but in the end =e found it 6 the code indeed ta$es rdi that
it )asses to mutex6enter01 from LrootdirL, and hence the corru)ted )ointer.
162 7.0olaris;x86 !rashdum) Analysis
9.8.#nother 6*bit rashd!mp analysis example
3he follo=ing exam)le shall serve as an advice to device driver develo)ers/ Qno$ your
compiler options A
3he machine )aniced =ith the follo=ing messages/
panic2cpu!3/t/read[ffffffff8#-#*!!!:
:HK TOHP: t;pe[e 0Dpf Page fault1 rp[fffffe8!!!6b%be! addr[! occurred in module
IunixI due to a >Q?? pointer dereference
poBernoBd:
Dpf Page fault
:ad kernel fault at addr[!x!
pid[6!" pc[!xfffffffffb8$6ce6" sp[!xfffffe8!!!6b%cc8" eflags[!x#!$#%
cr!: 8!!-!!%%Cpg"Bp"ne"et"mp"pe7 cr&: 6f!Cxmme"fxsr"pge"mce"pae"pse7
cr$: ! cr%: &&ce!!! cr8: !
rdi: ! rsi: ffffffff8!ca!ee! rdx: fffffffffbc!$.ff
rcx: ! r8: ! r*: ffffffff8!a&.#b!
rax: ff rbx: ! rbp@ fffffe80006b3cf0
r#!: .6 r##: ffffffff r#$: ffffffff8!ca!ee!
r#%: fffffffffbe$6&!8 r#&: fffffffffbe$6&!! r#-: ffffffff8!#!ac!!
fsb: ffffffff8!!!!!!! gsb: fffffffffbc#ede! ds: &%
es: &% fs: ! gs: #c%
trp: e err: $ rip: fffffffffb8$6ce6
cs: $8 rfl: #!$#% rsp: fffffe8!!!6b%cc8
ss: %!
fffffe8!!!6b%af! unix:die4da 0fffffe8!!!!adc8!" #fb8!!ccf1
fffffe8!!!6b%bd! unix:trap4-ea 01
fffffe8!!!6b%be! unix:cmntrap4##b 01
fffffe8!!!6b%cf! unix:lock6tr;46 01
fffffe8!!!6b%d6! genunix:turnstile6block4#*e 01
fffffe8!!!6b%dc! unix:mutex6'ector6enter4%df 01
fffffe8!!!6b%df! genunix:releasef4&b 01
fffffe8!!!6b%ed! genunix:ioctl4c% 01
4n first glance, this loo$s li$e a generic 0olaris $ernel issue % only core $ernel modules
involved, right J &o immediate hint of any driver involvement A
Het, this )anic =as caused by a bug in the follo=ing driver module % it =as com)iled
=ith gcc, and the )mno)red)(one com)iler o)tion that is mandatory =as omitted/
7 ::modinfo
FK ?<HKHKKO SFUE OEA M<KQ?E >HME
2 ... 3
#$# fffffffff-#*6$b! ef! # poBernoB 0HMK PoBernoBJ #.#- 0HCPFCH11
2 ... 3
4n the follo=ing )ages, it>ll be sho=n =hat ha))ened here.
Eell, by no= =e $no= =hat to do in order to find out. 3he )anic message tells us it>s a
>Q?? )ointer dereference, so let>s disassemble the )anicing code, lock6tr;01, to find
out =hat it attem)ted to access/
7 lock6tr;::dis
lock6tr;: mo'b ,)!x#"dl
lock6tr;4$: mo'(b+ dl"rax
lock6tr;46: xc/gb dl"0rdi1
3his is an unusual instruction % e5-6an3e 7yte. 3here are loc$s in 0olaris Fthread
and dis)atcher loc$s, s)inloc$sG =hich don>t $ee) o=ner information li$e mutexes and
r=loc$s, but only $no= a binary state >loc$ed>;>free> based on the contents of a single
7.0olaris;x86 !rashdum) Analysis 16"
byte. (m)lementation of these loc$s re9uires an atomic ?chec$ if -yte contains &*<<
and if so =rite my value into it@ instruction % =hich is xc/gb on x86 Fon 01A2!, ldstub
=ould be usedG. 0o =e $no= it attem)ted to access memory at rdi % =hich, as the
)anic messages sho=, contains >Q??.
Ee therefore have to find out =here the caller of lock6tr;01 got that rdi from.
lock6tr;01, as mutex6enter01, doesn>t initialiKe a frame)ointer of its o=n and neither
)ushes any values to the stac$. 0o =e $no= that, as =ith the )revious exam)le, the
stac$trace misses to sho= the actual caller of lock6tr;01. 3he next re)orted return
address, turnstile6block4!x#*e, of course sho=s =hat>s in6bet=een/
7 turnstile6block4#*e::dis
2 ... 3
turnstile6block4!x#8a: mo'+ !x#e!0r#$1"rdi
turnstile6block4!x#*$: lea+ !x#e!0rbx1"rsi
turnstile6block4!x#**: call )!x$b* Cturnstile6interlock7
turnstile6block4!x#*e: testl eax"eax
and the saved rsp gives us the return address into the real caller of lock6tr;01/
2 ... 3
pid[6!" pc[!xfffffffffb8$6ce6" sp[!xfffffe8!!!6b%cc8" eflags[!x#!$#%
2 ... 3
cs: $8 rfl: #!$#% rsp: fffffe8!!!6b%cc8
2 ... 3
7 fffffe8!!!6b%cc8/p
!xfffffe8!!!6b%cc8: turnstile6interlock4!x$$
7 Efffffe8!!!6b%cc8::dis
turnstile6interlock46: pus/+ r#%
turnstile6interlock48: mo'+ rdi"r#%
turnstile6interlock4!xb: pus/+ r#$
turnstile6interlock4!xd: mo'+ rsi"r#$
turnstile6interlock4!x#!: pus/+ rbx
turnstile6interlock4!x##: mo'+ 0r#$1"rbx
turnstile6interlock4!x#-: cmp+ r#%"rbx
turnstile6interlock4!x#8: Te 4!x$8 Cturnstile6interlock4!x&!7
turnstile6interlock4!x#a: mo'+ rbx"!rdi
turnstile6interlock4!x#d: call )!x#cf88d Clock6tr;7
turnstile6interlock4!x$$: testl eax"eax
2 ... 3
7 turnstile6interlock::dis
turnstile6interlock: pus/+ rbp
turnstile6interlock4#: mo'+ rsp"rbp
turnstile6interlock4&: pus/+ r#&
turnstile6interlock46: pus/+ r#%
2 ... 3
Ee could cheat and loo$ u) the sourcecode in order to determine =hat this function
does, but since =e>ve not made it )ast the first lock6tr;01 =e>ll get by Bust reverse6
engineering the first )iece of it. (t obviously gets t=o arguments in rdi and rsi,
=hich it % for later re6use after ma$ing some function calls of its o=n % stuffs into the
nonvolatile registers r#% F1
st
argG and r#$ F2
nd
argG. (t dereferences the second
argument, mo'+ 0r#$1"rbx, and com)ares =hat it )ointed to =ith the first. (f these
t=o =ere e9ual, it>d have ta$en the Te to Cturnstile6interlock4!x&!7, but since
they obviously have not been it moves Warg2 into Yrdi and calls loc$StryFG on that.
-ecause =e do have a ! )rototy)e for lock6tr;01 in Cs;s/mac/lock./7/
extern int lock6tr;0lock6t Elp1W
=e can derive the )rototy)e and first )iece of code for turnstile6interlock01 from
=hat =e>ve Bust found out. (t must>ve started li$e this/
16. 7.0olaris;x86 !rashdum) Analysis
... turnstile6interlock0lock6t Elock#" lock6t EEplock$1
V
lock6t Etmplock [ Eplock$W
if 0tmplock J[ lock#1
lock6tr;0tmplock1W
2 ... 3
Ehat =as that 2
nd
arg to this function J
0ince it =as stuffed into Yr12, and that didn>t get modified anymore after=ards, =e
can ta$e it from the )anic message. 3here =e find/
2 ... 3
r#!: .6 r##: ffffffff r#$: ffffffff8!ca!ee!
r#%: fffffffffbe$6&!8 r#&: fffffffffbe$6&!! r#-: ffffffff8!#!ac!!
2 ... 3
7 ffffffff8!ca!ee!/8
!xffffffff8!ca!ee!: !
0o arg1, =hich =ent into r#%, =as !xfffffffffbe$6&!8, and arg2, still in r#$, =as
!xffffffff8!ca!ee! and it really )ointed to a >Q??.
'o for the next frame, turnstile6block01 calling turnstile6interrupt01, and dig
out =here the arguments came from again/
7 ,C
fffffe8!!!6b%cf! lock6tr;4601
fffffe8!!!6b%d6! turnstile6block4!x#*e01
fffffe8!!!6b%dc! mutex6'ector6enter4!x%df01
fffffe8!!!6b%df! releasef4!x&b01
fffffe8!!!6b%ed! ioctl4!xc%01
fffffe8!!!6b%f$! s;s6s;scall%$4!xd*01
!!!!!!!!!!!!!%$! !x8!&.b&801
7 turnstile6block4!x#*e::dis
2 ... 3
turnstile6block4!x#8a: mo'+ !x#e!0r#$1"!rdi
turnstile6block4!x#*$: lea+ !x#e!0rbx1"!rsi
turnstile6block4!x#**: call )!x$b* Cturnstile6interlock7
turnstile6block4!x#*e: testl eax"eax
Hmm % it too$ them from memory referenced via nonvolatile registers rbx and r#$.
Ee>d have t=o immediate =ays for=ard no=/
1. 3he com)licated one % disassemble turnstile6block01, and attem)t to reverse
engineer =here the values in r#$ and rbx at that time came from.
0ince =e>re already dee) do=n in the function, =e>re not going that =ay. 2ather/
2. 3he sim)ler one % because rbx and r#$ are nonvolatile, the called function, in this
case turnstile6interlock01, of course has to either $ee) them as they are Fand
=e could find them in the tra)frame;)anic registers thenG, or save them to its stac$
so they can be restored on return Fbut as there =as no return =e>ll find them in the
stac$G.
-rings us bac$ to turnstile6interlock01, =hich indeed saves these t=o to its stac$
early on/
turnstile6interlock: pus/+ rbp
turnstile6interlock4#: mo'+ rsp"rbp
turnstile6interlock4&: pus/+ r#&
turnstile6interlock46: pus/+ r#%
turnstile6interlock48: mo'+ rdi"r#%
turnstile6interlock4!xb: pus/+ r#$
turnstile6interlock4!xd: mo'+ rsi"r#$
7.0olaris;x86 !rashdum) Analysis 165
turnstile6interlock4!x#!: pus/+ rbx
&o= consider the stac$ contents. 3his function =rites to the stac$/
1. it>s caller>s frame)ointer, rbp
2. the nonvolatile registers r#&, r#%, r#$ and rbx, in that order.
". =hen it calls lock6tr;01, the return address.
0o =e can no= identify the stac$ contents/
2 ... 3
pid[6!" pc[!xfffffffffb8$6ce6" sp[!xfffffe8!!!6b%cc8" eflags[!x#!$#%
2 ... 3
cs: $8 rfl: #!$#% rsp: fffffe8!!!6b%cc8
2 ... 3
7 fffffe8!!!6b%cc8"./nap
!xfffffe8!!!6b%cc8:
!xfffffe8!!!6b%cc8: turnstile6interlock4!x$$
!xfffffe8!!!6b%cd!: !xffffffff8!ca!d!! rbx
!xfffffe8!!!6b%cd8: !xffffffff8#-#*!!! r#$
!xfffffe8!!!6b%ce!: !xffffffff8!a&.#8! r#%
!xfffffe8!!!6b%ce8: turnstile6table4!xd6! r#&
0xfffffe80006b3cf0: 0xfffffe80006b3d60 rbp
!xfffffe8!!!6b%cf8: turnstile6block4!x#*e
Ee can no= chec$ =here these args came from/
2 ... 3
turnstile6block4!x#8a: mo'+ !x#e!0r#$1"!rdi
turnstile6block4!x#*$: lea+ !x#e!0rbx1"!rsi
2 ... 3
7 !xffffffff8#-#*!!!4#e!/n8
!xffffffff8#-#*#e!:
fffffffffbe$6&!8 rdi * 1
st
arg
7 !xffffffff8!ca!d!!4#e![8
ffffffff8!ca!ee! rsi * 2
nd
arg #note+ [8 due to lea+$
3his is all =ell and consistent, but =e>re not further yet, and therefore still have to go
the long =ay, and determine =here turnstile6block01 got the values from that it
$ee)s in r#$ F!xffffffff8#-#*!!!G and rbx F!xffffffff8!ca!d!!G. Ee>re
)articularly interested in the latter, rbx % that>s =here the bad )ointer =hich got
)assed on came from. 7isassemble/
7 turnstile6block::dis J egrep ]r0#$Gbx1,]
turnstile6block4!x#!: pus/+ r#$
turnstile6block4!x#$: pus/+ rbx
turnstile6block4!x$6: mo'+ gs:!x#8"rbx
turnstile6block4!x%6: mo'+ rbx"r#$
turnstile6block4!x#.%: mo'+ rax"rbx
turnstile6block4!x#b%: mo'+ gs:!x#8"r#$
turnstile6block4!x$!$: pop+ rbx
turnstile6block4!x$!%: pop+ r#$
turnstile6block4!x$cb: mo'+ rbx"r#$
3he pus/;pop are )art of function )ro6 and e)ilogues so those don>t bother us FyetG.
3he mo'+ gs:!x#8"... is a curthread access, as sho=n before. 3he function also
moves rbx to r#$ t=o times, =hich doesn>t bother us either because =e =ant to
$no= =here rbx is from. 3he only )lace that sets rbx is mo'+ rax"rbx so let>s
loo$ at this area more closely/
7 turnstile6block4!x#.%::dis
turnstile6block4!x#&*: mo'+ )!x%80rbp1"rdx
turnstile6block4!x#&d: cmpl ,!x#"0rdx1
166 7.0olaris;x86 !rashdum) Analysis
of the caller,
turnstile6block01
turnstile6block4!x#-!: Te 4!x$%% Cturnstile6block4!x%8%7
turnstile6block4!x#-6: mo'+ !x880r#$1"rdx
turnstile6block4!x#-e: test+ rdx"rdx
turnstile6block4!x#6#: Te 4!x.! Cturnstile6block4!x#d#7
turnstile6block4!x#6%: xorl eax"eax
turnstile6block4!x#6-: mo'+ !x8!0r#$1"!rdi
turnstile6block4!x#6d: call E!x80rdx1
turnstile6block4!x#.!: test+ rax"rax
turnstile6block4!x#.%: mo'+ rax"rbx
turnstile6block4!x#.6: Te 4!x-b Cturnstile6block4!x#d#7
turnstile6block4!x#.8: mo'+ gs:!x#8"rax
turnstile6block4!x#8#: cmp+ rbx"rax
turnstile6block4!x#8&: Te 4!x$#f Cturnstile6block4!x%a%7
turnstile6block4!x#8a: mo'+ !x#e!0r#$1"!rdi
turnstile6block4!x#*$: lea+ !x#e!0rbx1"!rsi
turnstile6block4!x#**: call )!x$b* Cturnstile6interlock7
turnstile6block4!x#*e: testl eax"eax
2 ... 3
Hmm % a bit unfair, there>s a call through a function )ointer in there. -ut =e>re
fortunate % Bust a fe= lines above =e find/ mo'+ !x880r#$1"rdx. Ee already found
out =hat r#$ =as, and so getting this is straightfor=ard/
7 !xffffffff8#-#*!!!4!x88/8
!xffffffff8#-#*!88: fffffffffbc!$.$!
7 fffffffffbc!$.$!::B/atis
fffffffffbc!$.$! is mutex6sobT6ops4! in unix]s data segment
7 fffffffffbc!$.$!::B/att;pe
fffffffffbc!$.$! is fffffffffbc!$.$!4!" struct 6sobT6ops
7 fffffffffbc!$.$!::print )a Istruct 6sobT6opsI
V
fffffffffbc!$.$! sobT6t;pe [ !x#
fffffffffbc!$.$8 sobT6oBner [ mutex6oBner
fffffffffbc!$.%! sobT6unsleep [ turnstile6sta;6asleep
fffffffffbc!$.%8 sobT6c/ange6pri [ turnstile6c/ange6pri
X
Cortunately, =e $no= that one. mutex6oBner01 ta$es a mutex as arg, and returns a
$ernel thread )ointer For >Q??G. 3he argument comes from/
turnstile6block4!x#6-: mo'+ !x8!0r#$1"rdi
7 !xffffffff8#-#*!!!4!x8!/8
!xffffffff8#-#*!8!: ffffffff8!#!ac!!
7 ffffffff8!#!ac!!::mutex
HKKO TSPE ME?K MF>SP? <?KSP? PHFTEOS
ffffffff8!#!ac!! adapt ffffffff8!ca!d!! ) ) ;es
3he o=ner of this mutex is in fact thread !xffffffff8!ca!d!! % =hich is in rbx, so
=e>ve found =here this has come from.
And =e seem no further. Ehere is that corru)tion any=ay J Are =e stuc$ J
3he ans=er is sim)ler than that. 7o some consisteny chec$s on the ?mutex@ and the
?o=ner thread@ above/
7 ffffffff8!#!ac!!::B/atis
ffffffff8!#!ac!! is in t/read fffffffffbc#dac!]s stack
7 ffffffff8!#!ac!!::B/att;pe
ffffffff8!#!ac!! is ffffffff8!#!aa8!4#8!" possibl; one of t/e folloBing:
'oid 0from fffffffffbc.a.a!4%8" t;pe struct 'fs1
struct ufs'fs 0from ffffffff8!c*$!!84c8" t;pe inode6t1
7 ffffffff8!ca!d!!::B/atis
7.0olaris;x86 !rashdum) Analysis 167
ffffffff8!ca!d!! is in t/read fffffffffbc#dac!]s stack
7 ffffffff8!ca!d!!::B/att;pe
ffffffff8!ca!d!! is ffffffff8!ca!d!!4!" possibl; one of t/e folloBing:
struct ml6unit at ffffffff8!ca!d!# 0from ffffffff8!#!aa8!4#8!" t;pe
struct ufs'fs1
'oid at ffffffff8!ca!e$! 0from ffffffff8!a&.%!!4#!" t;pe struct turnstile1
Hmm % this loo$s )retty bad. mdb tells us that both these values, the ?mutex@ and the
?o=ner@ are in some thread>s stac$ % and at best, are some ufs ty)e data structures.
3he attem)t to use the ?o=ner@ as a thread struct fails 9uite horribly/
7 ::load /opt/CTEact/mdb/-.#!/amd6&/act.so
7 ffffffff8!ca!d!!::act6t/read
EEE
could not get pid baddcafebaddcafe for proc ffffffff8!6a*e$! t/read
ffffffff8!ca!d!!
t/read sBapped
t/read addr ffffffff8!ca!d!!" proc addr ffffffff8!6a*e$!" lBp addr !
T/read beacb!!&b66!! is pinned b; t/is t/read
T/read bound to cpu id !xfbc.a.a!
t6state is !xffffffff ) illegal 'alue ) c/eck
Sc/eduling info:
t6pri is !x$!" t6epri is !" t6cid is !x8!#$.#&!
t)7t6cid out of bounds
t6disp6time: is !" !
last ran: % /ours %* mins #& secs ago" % /ours %* mins #! secs before panic
last ran cpu is corrupt !x6d6!!!!!6d6!!!t6stk !
stack trace is:
ffffffff8!ca!bc! 01
2 ... 3
3hat ma$es no sense. 3his ?mutex@ is no mutex, and this ?o=ner@ is no thread.
Eith this $no=ledge in mind, it ma$es sense to s$i) further reverse engineering
attem)ts on turnstile6block01, =hich seems more than incom)rehensible based on
the assembly code only, and go bac$ to the stac$trace instead/
7 ,C
fffffe80006b3cf0 lock6tr;4601
fffffe8!!!6b%d6! turnstile6block4!x#*e01
fffffe8!!!6b%dc! mutex6'ector6enter4!x%df01
fffffe8!!!6b%df! releasef4!x&b01
fffffe8!!!6b%ed! ioctl4!xc%01
fffffe8!!!6b%f$! s;s6s;scall%$4!xd*01
!!!!!!!!!!!!!%$! !x8!&.b&801
<et>s investigate the call to mutexSenterFG, and see =hether =e can find out =hat
mutex =as )assed in. 0hould =e in fact find that the caller of mutexSenterFG )assed
that ?non6mutex@ 5xffffffff8515ac55, then =e $no= the bug must be there % one cannot
call mutexSenterFG =ith Bust some more6or6less arbitrary address and ho)e all =ill be
fine A
Cor those =ho li$e to )ee$ ahead, cheat and use ::act6t/read/
7 Epanic6t/read::act6t/read
EEE
168 7.0olaris;x86 !rashdum) Analysis
t/read addr ffffffff8#-#*!!!" proc addr !" lBp addr ffffffff8#-#*!!!
T/read bound to cpu id !
2 ... 3
stack trace is:
2 ... 3
unix: lock6tr;unix: lock6tr;46 01
genunix: turnstile6interlock 05"!xffffffff8!ca!ee!1
genunix: turnstile6block4!x#*e 0!"!"!xffffffff8!#!ac!!"mutex6sobT6ops"!"!1
EEEEEEEEEE
failed to find mutex pointer in stack frames fffffe8!!!6b%dc!
EEEEEEEEEE
unix: mutex6'ector6enter4!x%df 0!xffffffff8!#!ac!!1
unix: mutex6enter 051
genunix: releasef4!x&b 0!x%!1
genunix: ioctl4!xc% 0!x6b%f$!"!xfb8!##&*"%1
unix: s;s6s;scall%$4!xd* 01
And bingo % mutex6'ector6enter01 =as called =ith this ?thing@.
-ut then, =e can of course find that from the caller, releasefFG, as =ell. 7isassembly/
releasef4!x%a: mo'+ !x#80r#&1"rbx
releasef4!x%e: lea+ !x!0r#%"rbx1"r#$
releasef4!x&%: mo'+ r#$"rdi
releasef4!x&6: call )!x#$#$&6 Cmutex6enter7
releasef4!x&b: mo'+ !x#80r#&1"rax
0o =e need to find r#$, and r#%;r#&;rbx if =e =ant to $no= =here it came from.
All these are nonvolatile registers, and if =e>re luc$y, mutex6'ector6enter01 =ill have
saved them for us.
<et>s chec$ its )rologue/
mutex6'ector6enter: pus/+ rbp
mutex6'ector6enter4#: mo'+ rsp"rbp
mutex6'ector6enter4&: pus/+ r#-
mutex6'ector6enter46: mo'+ rdi"r#-
mutex6'ector6enter4*: pus/+ r#&
mutex6'ector6enter4!xb: pus/+ r#%
mutex6'ector6enter4!xd: pus/+ r#$
mutex6'ector6enter4!xf: pus/+ rbx
mutex6'ector6enter4!x#!: sub+ ,!x$8"rsp
3hey>re all there. <oo$ing at the stac$/
2 ... 3
fffffe80006b3dc0 mutex6'ector6enter4!x%df01
2 ... 3
7 fffffe8!!!6b%dc!)%!"#!/nap
!xfffffe8!!!6b%d*!:
!xfffffe8!!!6b%d*!: !xfffff%ffd-*6e8*e
!xfffffe8!!!6b%d*8: !xffffffff8!#!a!!! rbx
!xfffffe8!!!6b%da!: !xffffffff8!#!ac!! r#$
!xfffffe8!!!6b%da8: !xc!! r#%
!xfffffe8!!!6b%db!: !xffffffff8!e$d.!8 r#&
!xfffffe8!!!6b%db8: ! r#-
0xfffffe80006b3dc0: 0xfffffe80006b3df0 rbp
!xfffffe8!!!6b%dc8: releasef4!x&b
2 ... 3
7.0olaris;x86 !rashdum) Analysis 16
s
t
a
c
$

g
r
o
=
t
h
t
o
=
a
r
d
s

l
o
=
e
r
a
d
d
r
e
s
s
e
s
releasef4!x%a: mo'+ !x#80r#&1"rbx
releasef4!x%e: lea+ !x!0r#%"rbx1"r#$
2 ... 3
7 !xffffffff8!e$d.!84#8/n8
!xffffffff8!e$d.$!:
ffffffff8!#!a!!!
7 ffffffff8!#!a!!!4!xc!![8
ffffffff8!#!ac!!
0o there it is. 3he address of something that =as not a )ointer to a mutex =as )assed
into mutex6enter01.
Ehere did releasef01 ta$e r#%;r#&;rbx from/
releasef: pus/+ rbp
releasef4#: mo'+ rsp"rbp
releasef4&: pus/+ r#&
releasef46: pus/+ r#%
releasef48: pus/+ r#$
releasef4!xa: pus/+ rbx
releasef4!xb: mo'l edi"ebx
releasef4!xd: mo'+ gs:!x#8"rax
releasef4!x#6: mo'+ !x#.80rax1"r#&
releasef4!x#d: mo'sl+ ebx"r#%
releasef4!x$!: s/l+ ,!x6"r#%
releasef4!x$&: call )!x&f& Cclear6acti'e6fd7
releasef4!x$*: add+ ,!xa%!"r#&
releasef4!x%!: Tmp 4!xa Creleasef4!x%a7
2 ... 3
releasef4!x%a: mo'+ !x#80r#&1"rbx
releasef4!x%e: lea+ !x!0r#%"rbx1"r#$
releasef4!x&%: mo'+ r#$"rdi
releasef4!x&6: call )!x#$#$&6 Cmutex6enter7
Ee didn>t ma$e it further than that, so the relevant instructions are/
Cor r#&/
releasef4!xd: mo'+ gs:!x#8"rax
releasef4!x#6: mo'+ !x#.80rax1"r#&
2 ... 3
releasef4!x$*: add+ ,!xa%!"r#&
7 Epanic6t/read4!x#.8/n8
!xffffffff8#-#*#.8:
ffffffff8!e$ccd8
7 Epanic6t/read::print )a kt/read6t J grep ffffffff8#-#*#.8
ffffffff8#-#*#.8 t6procp [ !xffffffff8!e$ccd8
7 ffffffff8!e$ccd84a%![8
ffffffff8!e$d.!8
7 ffffffff8!e$ccd8::print )a proc6t J grep ffffffff8!e$d.!8
ffffffff8!e$d.!8 u6finfo [ V
ffffffff8!e$d.!8 fi6lock [ V
ffffffff8!e$d.!8 6opa+ue [ 2 ! 3
Cor rbx/
releasef4!x%a: mo'+ !x#80r#&1"rbx
7 !xffffffff8!e$d.!84#8/n8
!xffffffff8!e$d.$!:
ffffffff8!#!a!!!
and finally r#%/
releasef4!xb: mo'l edi"ebx
2 ... 3
175 7.0olaris;x86 !rashdum) Analysis
releasef4!x#d: mo'sl+ ebx"r#%
releasef4!x$!: s/l+ ,!x6"r#%
3his ta$es the first argument, edi Fobviously an intG of releasef01, sign6extends it
to 6.bit and shifts it left by 5x6 Fi.e. multi)les it by 2
6
XX 6.G.
Ee need the arg to releasef01. 0ince that code in itself didn>t save edi any=here,
=e have to chec$ the caller/
7 ,C
2 ... 3
fffffe80006b3df0 releasef4!x&b01
fffffe80006b3ed0 ioctl4!xc%01
2 ... 3
7 ioctl4!xc%::dis
2 ... 3
ioctl4!xbb: mo'l r#&d"!edi
ioctl4!xbe: call )!x#!*#e Creleasef7
ioctl4!xc%: mo'l )!xcc0rbp1"eax
2 ... 3
(t ta$es the value from nonvolatile register r#&d. 'iven that releasef01 has saved
ioctl01>s r#& in its )rologue, =e can find it in the stac$//
releasef: pus/+ rbp
releasef4#: mo'+ rsp"rbp
releasef4&: pus/+ r#&
7 fffffe8!!!6b%df!)8"%/nap
!xfffffe8!!!6b%de8:
!xfffffe8!!!6b%de8: !x%!
0xfffffe80006b3df0: 0xfffffe80006b3ed0
!xfffffe8!!!6b%df8: ioctl4!xc%
7 !x%!E!t6&[9
c!!
0o the argument =as !x%!, and !xc!! is the result of the CC6. &ext ste) of course is to
determine =here ioctlFG got its Yr1. from. !hec$ the assembly/
7 ioctl::dis
ioctl: pus/+ rbp
ioctl4#: mo'+ rsp"rbp
ioctl4&: sub+ ,!xd!"rsp
ioctl4!xb: mo'+ r#$")!x$!0rbp1
ioctl4!xf: mo'+ r#%")!x#80rbp1
ioctl4!x#%: mo'l esi"r#%d
ioctl4!x#6: mo'+ r#&")!x#!0rbp1
ioctl4!x#a: mo'+ r#-")!x80rbp1
ioctl4!x#e: mo'l edi"r#&d
2 ... 3
ioctl4!xbb: mo'l r#&d"edi
ioctl4!xbe: call )!x#!*#e Creleasef7
ioctl4!xc%: mo'l )!xcc0rbp1"eax
(t does the same as =e>ve seen releasef01 do % move its first argument into the
nonvolatile register r#&d. Ehat =as the first argument of ioctl01 J
7 ,C
2 ... 3
fffffe8!!!6b%ed! ioctl4!xc%01
fffffe8!!!6b%f$! s;s6s;scall%$4!xd*01
2 ... 3
7 s;s6s;scall%$4!xd*::dis
s;s6s;scall%$4!xbc: mo'l !x!0rsp1"!edi
s;s6s;scall%$4!xc!: mo'l !x80rsp1"!esi
7.0olaris;x86 !rashdum) Analysis 171
s;s6s;scall%$4!xc&: mo'l !x#!0rsp1"!edx
s;s6s;scall%$4!xc8: mo'l !x#80rsp1"!ecx
s;s6s;scall%$4!xcc: mo'l !x$!0rsp1"!r8d
s;s6s;scall%$4!xd#: mo'l !x$80rsp1"!r9d
s;s6s;scall%$4!xd6: call E!x#80rbx1
s;s6s;scall%$4!xd*: mo'+ rbp"rsp
3his code obviously transforms "2bit argument )assing conventions Fon the stac$G into
6.bit argument )assing conventions Fin the arg registersG. Ee therefore need the
stac$)ointer at the time ioctlFG =as called and retrieve its first argument from there.
3he tas$ is of course easy % there>s a call being done, and if =e locate the return
address from that in the stac$ =e immediately $no= that the six =ords follo=ing it
contains the arguments/
2 ... 3
fffffe80006b3ed0 ioctl4!xc%01
2 ... 3
7 fffffe80006b3ed0"8/nap
0xfffffe80006b3ed0:
0xfffffe80006b3ed0: 0xfffffe80006b3f20
!xfffffe8!!!6b%ed8: s;s6s;scall%$4!xd*
!xfffffe8!!!6b%ee!: % edi
!xfffffe8!!!6b%ee8: !x&#&d&&!! esi
!xfffffe8!!!6b%ef!: ! edx
!xfffffe8!!!6b%ef8: ! ecx
!xfffffe8!!!6b%f!!: !xffffffff8#&$ac!! r8d
!xfffffe8!!!6b%f!8: !xffffffff8#-#*!!! r*d
&o= this is really strange % ioctl01 got called =ith % as 1
st
argument, and the code
claims to have )assed that through to releasef01. -ut this =as called =ith !x%! as 1
st
argument A
3his is a clear inconsistency. !an it be ex)lained J
3he only ex)lanation is that something corru)ted r#& in bet=een the instruction at
ioctl4!x#e F=hich initialiKed itG and the call to releasef01 at ioctl4!xbe. And
indeed =e ma$e function calls there/
2 ... 3
ioctl4!x%$: call )!x#!ce$ Cgetf7
2 ... 3
ioctl4!x.6: call )!x#%!b&6 Cget6udatamodel7
2 ... 3
ioctl4!x8e: mo'+ !x#!0r#$1"rdi
ioctl4!x*%: mo'+ !x#b!0rax1"r8
ioctl4!x*a: lea+ )!xcc0rbp1"r*
ioctl4!xa#: mo'+ r#-"rdx
ioctl4!xa&: mo'l r#%d"esi
ioctl4!xa.: call 4!xb**6* Cfop6ioctl7
3he first t=o are not really sus)icious. Cor one, they>re =ell6$no=n and long6tried
$ernel functions, and second their code is 9uite sim)le. (t>s left as an exercise to the
reader to verify that these don>t modify r#& =ithout restoring it for their caller.
-ut the other function is more sus)icious % it>s a generic dis)atcher, and =ill ultimately
end u) in a de#ice dri#er entry )oint. Ee can find =hich one =ithout reverse
engineering fop6ioctl01, by chec$ing the )anicing )rocess> file table/
7 Epanic6t/read::print )a kt/read6t t6procp
ffffffff8#-#*#.8 t6procp [ !xffffffff8!e$ccd8
7 !xffffffff8!e$ccd8::pfiles
@K TSPE A><KE F>@<
172 7.0olaris;x86 !rashdum) Analysis
! CMO ffffffff8#$!##8! /de'ices/pseudo/mm`!:null
# OEN ffffffff8#--$!&! /etc/s'c/'olatile/site)poBernoB:default.log
$ OEN ffffffff8#--$!&! /etc/s'c/'olatile/site)poBernoB:default.log
% CMO ffffffff8#&fa&c! /de'ices/pseudo/poBernoB`!:poBernoB
& CMO ffffffff8#-e8*c! /de'ices/pseudo/acpidr'`!:acpidr'
- CMO ffffffff8#6%f8&! /de'ices/pseudo/kstat`!:kstat
Ee>re o)erating on file descri)tor [" % and that is the )o=erno= driver. Ehat>s the
ioctl0*e1 entry )oint for that J
7 ::modctl
M<KCT? M<KQ?E :FTS @?HNS OE@ @F?E
2 ... 3
ffffffff8#$6fdc8 ffffffff8#$6ea8! li !x!! ! dr'/poBernoB
7 ffffffff8#$6fdc8::print Istruct modctlI mod6linkage G
::print Istruct modlinkageI
V
ml6re' [ !x#
ml6linkage [ 2 modldr'#" !" !" !" !" !" ! 3
X
7 modldr'#::print Istruct modldr'I
V
dr'6modops [ mod6dri'erops
dr'6linkinfo [ !xfffffffff-#*6e.$ IHMK PoBernoBJ #.#- 0HCPFCH1I
dr'6de'6ops [ poBernoB6de'6ops
X
7 poBernoB6de'6ops::print Istruct de'6opsI de'o6cb6ops G
::print Istruct cb6opsI cb6ioctl
cb6ioctl [ poBernoB6ioctl
Eho =ould>ve guessed. <et>s loo$ into this/
7 poBernoB6ioctl::dis
poBernoB6ioctl: pus/+ rbp
poBernoB6ioctl4#: mo'+ rsp"rbp
poBernoB6ioctl4&: mo'+ rbx")!x$!0rbp1
poBernoB6ioctl48: mo'+ r#$")!x#80rbp1
poBernoB6ioctl4!xc: mo'+ r#%")!x#!0rbp1
poBernoB6ioctl4!x#!: mo'+ r#&")!x80rbp1
poBernoB6ioctl4!x#&: sub+ ,!x%!"rsp
2 ... 3
Eo= % bad bad bad.
Ehat does this code do J (t loo$s li$e it saves the nonvolatile registers into hidden
local variables, )...0rbp1, doesn>t it J
Eell % it may save them, but =hat it forgot to do and only does after=ards, is to
allocate stac9space for this A
.hat's a big nono in a preemptive 9ernel such as 0olaris. (f an interrupt occurs
before the sub+ ,!x%!"rsp has caught u) =ith the re9uired stac$s)ace allocation,
the values of rbx;r#$;r#% and r#& Bust =ritten to the stac$ =ill be clobbered by
the interru)t frame A
Ehich is )recisely =hat must have ha))ened. 2emember r#& contained !x%! on
return J Eell % chec$ any tra)frame;interru)t frame that occurred in $ernel, and you>ll
find at the very bottom of it/
panic2cpu!3/t/read[ffffffff8#-#*!!!:
:HK TOHP: t;pe[e 0Dpf Page fault1 rp[fffffe8!!!6b%be! addr[! occurred in module
IunixI due to a >Q?? pointer dereference
poBernoBd:
7.0olaris;x86 !rashdum) Analysis 17"
Dpf Page fault
:ad kernel fault at addr[!x!
pid[6!" pc[!xfffffffffb8$6ce6" sp[!xfffffe8!!!6b%cc8" eflags[!x#!$#%
2 ... 3
7 fffffe8!!!6b%be!::print )a Istruct regsI J tail )$
fffffe8!!!6b%cb8 r6ss [ !x%!
X
&o= this is =here the !x%! comes from % as the value of =KS6SE?, the $ernel 6.bit
data segment selector that is in ss =hen the $ernel runs.
Ee>ve seen code li$e this before % chec$ the if01 VX else statement source exam)le
in section 2.7.2. 3he '&* gcc com)iler generates code li$e this in 6.bit x86 as an
?o)timiKation@ if the )mno)red)(one com)ile flag is omitted. 3he A#76. *&(+ A-(
allo=s this for a))lication code % but a )reem)tive $ernel cannot allo= this due to the
=ay interru)ts =or$ on x86. 3herefore/
Solaris Dernel 5odules must be compiled =ith -mno-red-!one if gcc is used.
#orale/
(f you>re a develo)er, $no= your com)iler>s default o)tions A
9.8.1.4nwanted g optimiEations and the Solaris ,ernel
3he '&* gcc com)iler>s default behaviour =hen com)iling code for the $ernel code
model F)mcmodel[kernelG on 6.bit x86 =ith o)timiKation on F)<$ or even aboveG isn>t
com)atible =ith the 0olaris $ernel for several reasons/
1. 3he com)iler uses the stac$ redKone, although that behaviour is incom)atible =ith
$ernel code on all )reem)tive $ernels % =hether <inux, 0olaris or one of the W-07s.
(t>s essential to disable the use of the redKone via )mno)red)(one. 3he exam)le in
the )revious section should have sho=n ho= )roblematic it is to trace this bug.
2. 3he com)iler =ill attem)t to use builtin inline versions of functions li$e bcop;01,
memcp;01 and the str...01 function family. -ut gcc>s builtins can brea$ the $ernel
because floating )oint ; vector registers are not usable from $ernel mode.
3he use of builtins must be disabled via )fno)builtins.
". 3he com)iler by default assumes to be able to lin$ binaries =ith libgcc.a that
contains common ?utility@ code for gcc. 3his is not available for $ernel drivers,
=hich therefore must be com)iled =ith )ffreestanding, =hich instructs gcc to
create ?standalone@ code =ithout any de)endencies on external libraries;obBects.
.. 0ome gcc versions o)timiKe a=ay the use of the frame)ointer =hen s)ecifying )<$.
Ehile frame)ointer6less $ernel driver code =ill =or$, it is incom)atible =ith 73race.
!ode that is su))osed to be dynamically instrumented via 73race re,uires
frame)ointers. gcc can be instructed not to o)timiKe a=ay frame)ointers by using
the )fno)omit)framepointer o)tion. (t>s the default for gcc "..." as shi))ed =ith
0olaris 15.
3here are other gcc o)timiKations that don>t cause )roblems in all cases but still may
have negative im)act de)ending in ex)ectations of the sourcecode. Exam)les of these
=ould be/
5. gcc does =hat it calls strict aliasing % ty)e6based o)timiKation. (f this is on, the
com)iler o)timiKes data accesses de)ending on structure layout and the data ty)es
involved. Cor driver code, though, that may be a )roblem in cases =here packed
structures For ! unionsG are used to ma) e.g. device hard=are registers. Ehether
)fno)strict)aliasing is re9uired to disable this behaviour therefore de)ends on
the s)ecific code being com)iled.
17. 7.0olaris;x86 !rashdum) Analysis
6. gcc does o)timiKation li$e per! or cross!sourcefile function inlining or eliminating
functions that are tail!called only. 3his doesn>t cause failures but it may cause
undesirable results Ffunctions disa))earing =hich the develo)er ex)exts to see e.g.
in crashdum)s, or via 73raceG and can be disabled, via the o)tions 6fno)inline,
)fno)unit)at)a)time or )fno)optimi(e)sibling)calls.
Cor more gcc o)tions, see http://gcc.gnu.org/onlinedocs/gcc/, ?4)timiKations@.
7.0olaris;x86 !rashdum) Analysis 175
9.6.#()6* #6$ - 6a,traing witho!t framepointers
176 7.0olaris;x86 !rashdum) Analysis
9.9.%xamples on appliation ored!mp analysis on
Solaris=x86
7.0olaris;x86 !rashdum) Analysis 177
9.8.#d&aned )eb!gging Topis
9.8.1.The Solaris=x86 boot deb!gger
9.8.".)eb!gging hard hangs on Solaris=x86
178 7.0olaris;x86 !rashdum) Analysis
8./ab %xerises
8.1.$ntrod!tion to x86 assembly lang!age
1. &ame five different x866com)atible !1*s that run 0olaris 15.
ho= do they differ J
Ehich features does !1* + have but !1* H not, and vice versa J
Ehich of these features are being used in 0olaris 15 J
2. Ehy does 0olaris 15 not run on either of the follo=ing !1*s/
(ntel i8586,
(ntel i85286,
A#7 .86,
#otorola 685.5 J
Ehich ones of these run any version of 0olaris J
". !reate a file ?testfile@ =ith random contents using the follo=ing command/
dd if[/de'/random of[testfile bs[#!$& count[#
3ry to disassemble the contents of testfile using the command/
ec/o Y!"#!!5aiZ G mdb testfile
on a 0olaris 15;x86 machine
on a 0olaris 15;01A2! machine.
Ehat do you find J
.. 4n a machine running a 6.bit 0olaris 15;x86 $ernel, try disassembling testfile in
both "2bit and 6.bit disassembly mode using the follo=ing command/
mdb testfile CCE<F
::dismode ia%$W !"#!!5ai
::dismode amd6&W !"#!!5ai
E<F
(s there any difference bet=een the "2bit and 6.bit out)ut J
(f so, =hat is different J
5. Ehat is the x86 machine code for the follo=ing assembly instruction/
addb al"0eax1
6. 3a$e testfile created above and co)y it onto a 01A2! and a x86 machine. (ns)ect its
contents using the commands/
od )> #$8 )x testfile
8.<ab Exercises 17
od )> #$8 )t x# testfile
od )> #$8 )t x$ testfile
od )> #$8 )t x& testfile
od )> #$8 )t x8 testfile
!om)are the out)ut on 01A2! and x86 and describe =hat you see.
7. !reate the follo=ing assembly sourcefile/
/ amd6&)impl.s
/ demonstrate /oB HMK extended t/e x86 instruction set
.globl func
func:
addb bl" al
addb r##b" al
addb bl" r#!b
addb r##b" r#!b
addB bx" ax
addB r##B" ax
addB bx" r#!B
addB r##B" r#!B
addl ebx" eax
addl r##d" eax
addl ebx" r#!d
addl r##d" r#!d
add+ rbx" rax
add+ r##" rax
add+ rbx" r#!
add+ r##" r#!
.si(e func".)func
and assemble it Fdon>t forget )xarc/[amd6&, to instruct the assembler to use
A#76. in)ut modeG. 7isassemble the resulting obBect file via /usr/ccs/bin/dis.
(dentify the )atterns in the binary code.
=hat do all addb instructions have in common J
=hat do all addB instructions have in common J
... addl;add+ instructions J
=hat differs bet=een instructions using bl;bx;ebx;rbx and instructions using
the various =idths of r## J 7ito for rax;r#! J
!an you derive from the binary code ho= the A#76. extension =as done J
(f not/ 7isassemble the obBect file =ith mdb, s=itching into ia"2 disassembly mode
F::dismode ia%$G. Ehat>s the same and =hat>s different to the 6.bit version J
8. !reate the follo=ing assembly sourcefile/
/ addressing mode redundanc; in %$bit x86
/ demonstrate /oB rip)relati'e addressing is done in HMK6&
.globl func
func:
mo'l !x#$%&" ebx
.si(e func".)func
and assemble it Fcc )c ... for "2bit, cc )xarc/[amd6& )c ... for 6.bitG
Assemble it as "2bit, then disassemble the obBect file via /usr/ccs/bin/dis.
185 8.<ab Exercises
Assemble it as 6.bit, then disassemble the obBect file.
Ehat if any are the differences J &ext, !hange the source to/
func:
mo'l !x#$%&" ebx
mo'l !x#$%&0rip1" ebx
.si(e func".)func
Assemble this F6.bit re9uired no=, of courseG.
7isassemble it in mdb, using the commands/
::dismode amd6&W func::dis
::dismode ia%$W func::dis
Ho= =as the rip6relative addressing done in 6.bit mode J
. !om)ile the follo=ing sourcefile, into o)timiKed and non6o)timiKed "2bit and 6.bit
code, both =ith gcc and 0un Eor$sho) cc/
Dinclude Cstring./7
Dinclude Cstdlib./7
t;pedef struct 6str V
int str6iW
c/ar str6cW
long long str6llW
c/ar str6name2$-63W
struct 6str Estr6nxtW
X str6tW
'oid init6str0str6t Einitme" int i" c/ar c" long long ll" str6t Enxt1
V
str6t l'W
int TW
l'.str6i [ iW
l'.str6c [ cW
l'.str6ll [ llW
l'.str6nxt [ nxtW
for 0T [ cW T C iW T441
l'.str6name2T3 [ 0c/ar1TW
memcp;0initme" \l'" si(eof0str6t11W
X
Cor each case, disassemble the resulting binary and identify the instructions that
access the array, l'.str6name2T3. Ehat is used to access memory J
Ehat assembly code Fo)timiKed vs. non6o)timiKed, gcc vs. Eor$sho) ccG is best
readable J
15.!hange the above )rogram and ma$e l' a global Finstead of a localG variable.
2e)eat the ste)s above, for 6.bit o)timiKed com)ilation. Ehat changes J
11.!hange the )rogram again to directly initialiKe Einitme Fno )re6creation of an
instance of the structure and memc)yG. 1erform both "2bit and 6.bit o)timiKing
com)iles. Ehat changes in the assembly code J
8.<ab Exercises 181
12.!om)ile the follo=ing sourcecode/
int main0int argc" c/ar EEarg'1
V
return 0% E argc1W
/E
E tr; also:
E return 0- E argc1
E return 0* E 0argc 4 #11
E/
X
*se o)timiKation F)<$ or higher in gcc, )x<% or above in Eor$sho) ccG. Ehat
assembly instructions are used to )erform the multi)lication J
182 8.<ab Exercises
8.".Sta,s and Sta,traing
1. !om)ile the follo=ing )rogram into a 6.bit x86 executable/
Dinclude Cstdlib./7
Dinclude Cstdio./7
long
o'erfloB6me0long a#" long a$" long a%" long a&" long a-" long a6" long a.1
V
long local'arW
local'ar [ a# 4 a$ ) a% E a& / a- a a6 G a.W
return 0local'ar 4 o'erfloB6me0lrand&801" lrand&801" lrand&801"
lrand&801" lrand&801" lrand&801" lrand&80111W
X
int main0int argc" c/ar EEarg'1
V
printf0I?et]s o'erfloB: ld^nI"
o'erfloB6me0#" $" %" &" -" 6" .11W
return 0!1W
X
*se o)timiKation F)<$ in gcc, or )x<% in ccG because that ma$es the assembly code
better readable.
o)en the )rogram in mdb.
)ut a brea$)oint in main Fmain:bG
run the )rogram F:rG
Ehen the brea$)oint is hit, dum) the to) of the stac$ FCrsp"#!/napG. Ehat is on
the stac$ J
disassemble main and identify the instructions that )ut values into the stac$.
single6ste) through main and dum) the to) of the stac$ after each ste) to verify
your findings F:sWCrsp"#!/napG. 0to) singleste))ing =hen you>re in
o'erfloB6me at the first call lrand&8.
Ex)lain all the values on the stac$ bet=een the stac$)ointer at this time and the
frame)ointer of main.
Ehere does the stac$frame of main01 start, and =here does it end J 'ive the
addresses A
!an you find the arguments of main01 J
!ontinue the )rogram F:cG. (t =ill segfault % =hy J
2. A crashdum) is )rovided =ith the electronic )arts of the course material that has
the follo=ing stac$trace/
7 ,C
ffffffffb$ef8d&! mutex6enter4!xb01
ffffffffb$ef8e!! lookupnameat4!x8601
ffffffffb$ef8e-! cstatat6get'p4!x##-01
ffffffffb$ef8eb! cstatat6&6%$4!x&*01
ffffffffb$ef8ec! stat6&6%$4!x$$01
ffffffffb$ef8f$! s;s6s;scall%$4!xd!01
(dentify the stac$ boundaries Fbottom and to) of the stac$framesG for the listed
8.<ab Exercises 18"
functions. (.e. for all functions in the call trace, find/
Ehat is the first =ord =ritten to the stac$ by a function J
Ehat is the last =ord =ritten to the stac$ by the same function J
Cind out based on reading the assembly code for function and caller ho= many
arguments the listed functions have.
Cind the arguments. 3o do so, em)ly the follo=ing strategies/
load the act module and let that do the =or$ for you/
::load /opt/CTEact/mdb/-.#!/amd6&/act.so
Epanic6t/read::act6t/read
0earch them manually, at least for those cases =here act fails to )rint them. 3he
seach strategy is/
7isassemble the function.
0ee =hether it )uts arguments registers into its stac$.
(f it does, retrieve the values from the stac$ of the function.
0ee =hether it moves argument registers into nonvolatiles.
(f it does, disassemble the next function in the calltrace and see =here it
saves the nonvolatiles.
(f neither, disassemble the caller and see =here it ta$es the arguments from.
(f they come from local variables of the caller, they>ll be in the caller>s stac$.
(f they come from nonvolatile registers of the caller, they have been saved
by the function itself.
18. 8.<ab Exercises
>.+eferenes
1. Endianness Ehite)a)er
http://$$$.intel.com/design/intarch/papers/endian.pdf
2. External 7ata 2e)resentation 0tandard
http://$$$.ietf.org/rfc/rfc&F3.t%t
".
..
.2eferences 185
1@./iense
3he first version of this boo$ =as =ritten by Cran$ Hofmann.
Hou>re allo=ed to modify this under the terms and conditions stated by the !reative
!ommons ?Attribution60hareAli$e@ <icense, 8ersion 2.5/
http://creati#ecommons.org/licenses/by!sa/3.B/
0ummary/
Attribution8+hareAli9e 2.5
Eou are free1
to co)y, distribute, dis)lay, and )erform the =or$
to ma$e derivative =or$s
to ma$e commercial use of the =or$
6nder the follo=ing conditions1
Attribution. Hou must attribute the =or$ in the
manner s)ecified by the author or licensor.
Share Ali9e. (f you alter, transform, or build u)on this
=or$, you may distribute the resulting =or$ only under
a license identical to this one.
Cor any reuse or distribution, you must ma$e clear to others the license terms of
this =or$.
Any of these conditions can be =aived if you get )ermission from the co)yright
holder.
Eour fair use and other rights are in no =ay affected by the above.
15.<icense 187
Cull terms in )rint/
Attribution8+hareAli9e 2.5
!2EA3(8E !4##4&0 !42142A3(4& (0 &43 A <AE C(2# A&7 74E0 &43
1248(7E <E'A< 0E28(!E0. 7(032(-*3(4& 4C 3H(0 <(!E&0E 74E0 &43 !2EA3E
A& A3342&EH6!<(E&3 2E<A3(4&0H(1. !2EA3(8E !4##4&0 1248(7E0 3H(0
(&C42#A3(4& 4& A& LA06(0L -A0(0. !2EA3(8E !4##4&0 #A:E0 &4
EA22A&3(E0 2E'A27(&' 3HE (&C42#A3(4& 1248(7E7, A&7 7(0!<A(#0
<(A-(<(3H C42 7A#A'E0 2E0*<3(&' C24# (30 *0E.
?icense
3HE E42: FA0 7EC(&E7 -E<4EG (0 1248(7E7 *&7E2 3HE 3E2#0 4C 3H(0
!2EA3(8E !4##4&0 1*-<(! <(!E&0E FL!!1<L 42 L<(!E&0ELG. 3HE E42: (0
1243E!3E7 -H !41H2('H3 A&7;42 43HE2 A11<(!A-<E <AE. A&H *0E 4C 3HE
E42: 43HE2 3HA& A0 A*3H42(^E7 *&7E2 3H(0 <(!E&0E 42 !41H2('H3 <AE
(0 124H(-(3E7.
-H E+E2!(0(&' A&H 2('H30 34 3HE E42: 1248(7E7 HE2E, H4* A!!E13 A&7
A'2EE 34 -E -4*&7 -H 3HE 3E2#0 4C 3H(0 <(!E&0E. 3HE <(!E&042 '2A&30
H4* 3HE 2('H30 !4&3A(&E7 HE2E (& !4&0(7E2A3(4& 4C H4*2 A!!E13A&!E
4C 0*!H 3E2#0 A&7 !4&7(3(4&0.
$. Definitions
a. F,ollective 8or9F means a =or$, such as a )eriodical issue, anthology or
encyclo)edia, in =hich the Eor$ in its entirety in unmodified form, along =ith a
number of other contributions, constituting se)arate and inde)endent =or$s in
themselves, are assembled into a collective =hole. A =or$ that constitutes a
!ollective Eor$ =ill not be considered a 7erivative Eor$ Fas defined belo=G for
the )ur)oses of this <icense.
b. FDerivative 8or9F means a =or$ based u)on the Eor$ or u)on the Eor$ and
other )re6existing =or$s, such as a translation, musical arrangement,
dramatiKation, fictionaliKation, motion )icture version, sound recording, art
re)roduction, abridgment, condensation, or any other form in =hich the Eor$
may be recast, transformed, or ada)ted, exce)t that a =or$ that constitutes a
!ollective Eor$ =ill not be considered a 7erivative Eor$ for the )ur)ose of this
<icense. Cor the avoidance of doubt, =here the Eor$ is a musical com)osition or
sound recording, the synchroniKation of the Eor$ in timed6relation =ith a
moving image FLsynchingLG =ill be considered a 7erivative Eor$ for the )ur)ose
of this <icense.
c. F/icensorF means the individual or entity that offers the Eor$ under the terms
of this <icense.
d. FOriginal AuthorF means the individual or entity =ho created the Eor$.
e. F8or9F means the co)yrightable =or$ of authorshi) offered under the terms of
this <icense.
f. FEouF means an individual or entity exercising rights under this <icense =ho
has not )reviously violated the terms of this <icense =ith res)ect to the Eor$, or
=ho has received ex)ress )ermission from the <icensor to exercise rights under
this <icense des)ite a )revious violation.
188 15.<icense
g. F/icense 0lementsF means the follo=ing high6level license attributes as
selected by <icensor and indicated in the title of this <icense/ Attribution,
0hareAli$e.
". ;air 6se +ights. &othing in this license is intended to reduce, limit, or restrict any
rights arising from fair use, first sale or other limitations on the exclusive rights of the
co)yright o=ner under co)yright la= or other a))licable la=s.
!. /icense 4rant. 0ubBect to the terms and conditions of this <icense, <icensor
hereby grants Hou a =orld=ide, royalty6free, non6exclusive, )er)etual Ffor the duration
of the a))licable co)yrightG license to exercise the rights in the Eor$ as stated belo=/
a. to re)roduce the Eor$, to incor)orate the Eor$ into one or more !ollective
Eor$s, and to re)roduce the Eor$ as incor)orated in the !ollective Eor$sN
b. to create and re)roduce 7erivative Eor$sN
c. to distribute co)ies or )honorecords of, dis)lay )ublicly, )erform )ublicly, and
)erform )ublicly by means of a digital audio transmission the Eor$ including as
incor)orated in !ollective Eor$sN
d. to distribute co)ies or )honorecords of, dis)lay )ublicly, )erform )ublicly, and
)erform )ublicly by means of a digital audio transmission 7erivative Eor$s.
e. Cor the avoidance of doubt, =here the =or$ is a musical com)osition/
i. *erformance +oyalties 6nder 2lan9et /icenses. <icensor =aives the
exclusive right to collect, =hether individually or via a )erformance rights
society Fe.g. A0!A1, -#(, 0E0A!G, royalties for the )ublic )erformance or
)ublic digital )erformance Fe.g. =ebcastG of the Eor$.
ii. 5echanical +ights and Statutory +oyalties. <icensor =aives the
exclusive right to collect, =hether individually or via a music rights
society or designated agent Fe.g. Harry Cox AgencyG, royalties for any
)honorecord Hou create from the Eor$ FLcover versionLG and distribute,
subBect to the com)ulsory license created by 17 *0! 0ection 115 of the
*0 !o)yright Act For the e9uivalent in other BurisdictionsG.
f. 8ebcasting +ights and Statutory +oyalties. Cor the avoidance of doubt,
=here the Eor$ is a sound recording, <icensor =aives the exclusive right to
collect, =hether individually or via a )erformance6rights society Fe.g.
0oundExchangeG, royalties for the )ublic digital )erformance Fe.g. =ebcastG of
the Eor$, subBect to the com)ulsory license created by 17 *0! 0ection 11. of
the *0 !o)yright Act For the e9uivalent in other BurisdictionsG.
3he above rights may be exercised in all media and formats =hether no= $no=n or
hereafter devised. 3he above rights include the right to ma$e such modifications as are
technically necessary to exercise the rights in other media and formats. All rights not
ex)ressly granted by <icensor are hereby reserved.
7. +estrictions.3he license granted in 0ection " above is ex)ressly made subBect to
and limited by the follo=ing restrictions/
a. Hou may distribute, )ublicly dis)lay, )ublicly )erform, or )ublicly digitally
)erform the Eor$ only under the terms of this <icense, and Hou must include a
co)y of, or the *niform 2esource (dentifier for, this <icense =ith every co)y or
)honorecord of the Eor$ Hou distribute, )ublicly dis)lay, )ublicly )erform, or
)ublicly digitally )erform. Hou may not offer or im)ose any terms on the Eor$
that alter or restrict the terms of this <icense or the reci)ients> exercise of the
rights granted hereunder. Hou may not sublicense the Eor$. Hou must $ee)
intact all notices that refer to this <icense and to the disclaimer of =arranties.
Hou may not distribute, )ublicly dis)lay, )ublicly )erform, or )ublicly digitally
)erform the Eor$ =ith any technological measures that control access or use of
the Eor$ in a manner inconsistent =ith the terms of this <icense Agreement.
15.<icense 18
3he above a))lies to the Eor$ as incor)orated in a !ollective Eor$, but this
does not re9uire the !ollective Eor$ a)art from the Eor$ itself to be made
subBect to the terms of this <icense. (f Hou create a !ollective Eor$, u)on notice
from any <icensor Hou must, to the extent )racticable, remove from the
!ollective Eor$ any credit as re9uired by clause .FcG, as re9uested. (f Hou create
a 7erivative Eor$, u)on notice from any <icensor Hou must, to the extent
)racticable, remove from the 7erivative Eor$ any credit as re9uired by clause
.FcG, as re9uested.
b. Hou may distribute, )ublicly dis)lay, )ublicly )erform, or )ublicly digitally
)erform a 7erivative Eor$ only under the terms of this <icense, a later version
of this <icense =ith the same <icense Elements as this <icense, or a !reative
!ommons i!ommons license that contains the same <icense Elements as this
<icense Fe.g. Attribution60hareAli$e 2.5 Ra)anG. Hou must include a co)y of, or
the *niform 2esource (dentifier for, this <icense or other license s)ecified in the
)revious sentence =ith every co)y or )honorecord of each 7erivative Eor$ Hou
distribute, )ublicly dis)lay, )ublicly )erform, or )ublicly digitally )erform. Hou
may not offer or im)ose any terms on the 7erivative Eor$s that alter or restrict
the terms of this <icense or the reci)ients> exercise of the rights granted
hereunder, and Hou must $ee) intact all notices that refer to this <icense and to
the disclaimer of =arranties. Hou may not distribute, )ublicly dis)lay, )ublicly
)erform, or )ublicly digitally )erform the 7erivative Eor$ =ith any
technological measures that control access or use of the Eor$ in a manner
inconsistent =ith the terms of this <icense Agreement. 3he above a))lies to the
7erivative Eor$ as incor)orated in a !ollective Eor$, but this does not re9uire
the !ollective Eor$ a)art from the 7erivative Eor$ itself to be made subBect to
the terms of this <icense.
c. (f you distribute, )ublicly dis)lay, )ublicly )erform, or )ublicly digitally )erform
the Eor$ or any 7erivative Eor$s or !ollective Eor$s, Hou must $ee) intact all
co)yright notices for the Eor$ and )rovide, reasonable to the medium or means
Hou are utiliKing/ FiG the name of the 4riginal Author For )seudonym, if
a))licableG if su))lied, and;or FiiG if the 4riginal Author and;or <icensor
designate another )arty or )arties Fe.g. a s)onsor institute, )ublishing entity,
BournalG for attribution in <icensor>s co)yright notice, terms of service or by
other reasonable means, the name of such )arty or )artiesN the title of the Eor$
if su))liedN to the extent reasonably )racticable, the *niform 2esource
(dentifier, if any, that <icensor s)ecifies to be associated =ith the Eor$, unless
such *2( does not refer to the co)yright notice or licensing information for the
Eor$N and in the case of a 7erivative Eor$, a credit identifying the use of the
Eor$ in the 7erivative Eor$ Fe.g., LCrench translation of the Eor$ by 4riginal
Author,L or L0creen)lay based on original Eor$ by 4riginal AuthorLG. 0uch
credit may be im)lemented in any reasonable mannerN )rovided, ho=ever, that
in the case of a 7erivative Eor$ or !ollective Eor$, at a minimum such credit
=ill a))ear =here any other com)arable authorshi) credit a))ears and in a
manner at least as )rominent as such other com)arable authorshi) credit.
G. +epresentations> 8arranties and Disclaimer
*&<E00 43HE2E(0E A'2EE7 34 -H 3HE 1A23(E0 (& E2(3(&', <(!E&042
4CCE20 3HE E42: A06(0 A&7 #A:E0 &4 2E12E0E&3A3(4&0 42 EA22A&3(E0
4C A&H :(&7 !4&!E2&(&' 3HE #A3E2(A<0, E+12E00, (#1<(E7, 03A3*342H 42
43HE2E(0E, (&!<*7(&', E(3H4*3 <(#(3A3(4&, EA22A&3(E0 4C 3(3<E,
#E2!HA&3(-(<(3H, C(3&E00 C42 A 1A23(!*<A2 1*2140E, &4&(&C2(&'E#E&3,
42 3HE A-0E&!E 4C <A3E&3 42 43HE2 7ECE!30, A!!*2A!H, 42 3HE
12E0E&!E 4C A-0E&!E 4C E22420, EHE3HE2 42 &43 7(0!48E2A-<E. 04#E
R*2(07(!3(4&0 74 &43 A<<4E 3HE E+!<*0(4& 4C (#1<(E7 EA22A&3(E0, 04
15 15.<icense
0*!H E+!<*0(4& #AH &43 A11<H 34 H4*.
-. /imitation on /iability. E+!E13 34 3HE E+3E&3 2EO*(2E7 -H A11<(!A-<E
<AE, (& &4 E8E&3 E(<< <(!E&042 -E <(A-<E 34 H4* 4& A&H <E'A< 3HE42H
C42 A&H 01E!(A<, (&!(7E&3A<, !4&0EO*E&3(A<, 1*&(3(8E 42 E+E#1<A2H
7A#A'E0 A2(0(&' 4*3 4C 3H(0 <(!E&0E 42 3HE *0E 4C 3HE E42:, E8E& (C
<(!E&042 HA0 -EE& A78(0E7 4C 3HE 1400(-(<(3H 4C 0*!H 7A#A'E0.
&. .ermination
a. 3his <icense and the rights granted hereunder =ill terminate automatically
u)on any breach by Hou of the terms of this <icense. (ndividuals or entities =ho
have received 7erivative Eor$s or !ollective Eor$s from Hou under this
<icense, ho=ever, =ill not have their licenses terminated )rovided such
individuals or entities remain in full com)liance =ith those licenses. 0ections 1,
2, 5, 6, 7, and 8 =ill survive any termination of this <icense.
b. 0ubBect to the above terms and conditions, the license granted here is )er)etual
Ffor the duration of the a))licable co)yright in the Eor$G. &ot=ithstanding the
above, <icensor reserves the right to release the Eor$ under different license
terms or to sto) distributing the Eor$ at any timeN )rovided, ho=ever that any
such election =ill not serve to =ithdra= this <icense For any other license that
has been, or is re9uired to be, granted under the terms of this <icenseG, and this
<icense =ill continue in full force and effect unless terminated as stated above.
'. 5iscellaneous
a. Each time Hou distribute or )ublicly digitally )erform the Eor$ or a !ollective
Eor$, the <icensor offers to the reci)ient a license to the Eor$ on the same
terms and conditions as the license granted to Hou under this <icense.
b. Each time Hou distribute or )ublicly digitally )erform a 7erivative Eor$,
<icensor offers to the reci)ient a license to the original Eor$ on the same terms
and conditions as the license granted to Hou under this <icense.
c. (f any )rovision of this <icense is invalid or unenforceable under a))licable la=,
it shall not affect the validity or enforceability of the remainder of the terms of
this <icense, and =ithout further action by the )arties to this agreement, such
)rovision shall be reformed to the minimum extent necessary to ma$e such
)rovision valid and enforceable.
d. &o term or )rovision of this <icense shall be deemed =aived and no breach
consented to unless such =aiver or consent shall be in =riting and signed by the
)arty to be charged =ith such =aiver or consent.
e. 3his <icense constitutes the entire agreement bet=een the )arties =ith res)ect
to the Eor$ licensed here. 3here are no understandings, agreements or
re)resentations =ith res)ect to the Eor$ not s)ecified here. <icensor shall not
be bound by any additional )rovisions that may a))ear in any communication
from Hou. 3his <icense may not be modified =ithout the mutual =ritten
agreement of the <icensor and Hou.
15.<icense 11
0reati#e 0ommons is not a party to this ?icense. and makes no $arranty $hatsoe#er
in connection $ith the Hork. 0reati#e 0ommons $ill not be liable to -ou or any party
on any legal theory for any damages $hatsoe#er. including $ithout limitation any
general. special. incidental or conse,uential damages arising in connection to this
license. @ot$ithstanding the foregoing t$o D3E sentences. if 0reati#e 0ommons has
e%pressly identified itself as the ?icensor hereunder. it shall ha#e all rights and
obligations of ?icensor.
(%cept for the limited purpose of indicating to the public that the Hork is licensed
under the 00:?. neither party $ill use the trademark N0reati#e 0ommonsN or any
related trademark or logo of 0reati#e 0ommons $ithout the prior $ritten consent of
0reati#e 0ommons. 5ny permitted use $ill be in compliance $ith 0reati#e 0ommons/
then!current trademark usage guidelines. as may be published on its $ebsite or
other$ise made a#ailable upon re,uest from time to time.
!reative !ommons may be contacted at http://creati#ecommons.org/.
12 15.<icense

You might also like