WWW.DUMAIS.IO
ARTICLES
OVERLAY NETWORKS WITH MY SDN CONTROLLERSIMPLE LEARNING SWITCH WITH OPENFLOWINSTALLING KUBERNETES MANUALLYWRITING A HYPERVISOR WITH INTEL VT-X CREATING YOUR OWN LINUX CONTAINERSVIRTIO DRIVER IMPLEMENTATIONNETWORKING IN MY OSESP8266 BASED IRRIGATION CONTROLLERLED STRIP CONTROLLER USING ESP8266.OPENVSWITCH ON SLACKWARESHA256 ASSEMBLY IMPLEMENTATIONPROCESS CONTEXT ID AND THE TLBTHREAD MANAGEMENT IN MY HOBBY OSENABLING MULTI-PROCESSORS IN MY HOBBY OSNEW HOME AUTOMATION SYSTEMINSTALLING AND USING DOCKER ON SLACKWARESYSTEM ON A CHIP EMULATORUSING JSSIP AND ASTERISK TO MAKE A WEBPHONEC++ WEBSOCKET SERVERSIP ATTACK BANNINGBLOCK CACHING AND WRITEBACKBEAGLEBONE BLACK BARE METAL DEVELOPEMENTARM BARE METAL DEVELOPMENTUSING EPOLLMEMORY PAGINGIMPLEMENTING HTTP DIGEST AUTHENTICATIONSTACK FRAME AND THE RED ZONE (X86_64)AVX/SSE AND CONTEXT SWITCHINGHOW TO ANSWER A QUESTION THE SMART WAY.REALTEK 8139 NETWORK CARD DRIVERREST INTERFACE ENGINECISCO 1760 AS AN FXS GATEWAYHOME AUTOMATION SYSTEMEZFLORA IRRIGATION SYSTEMSUMP PUMP MONITORINGBUILDING A HOSTED MAILSERVER SERVICEI AM NOW HOSTING MY OWN DNS AND MAIL SERVERS ON AMAZON EC2DEPLOYING A LAYER3 SWITCH ON MY NETWORKACD SERVER WITH RESIPROCATEC++ JSON LIBRARYIMPLEMENTING YOUR OWN MUTEX WITH CMPXCHGWAKEUPCALL SERVER USING RESIPROCATEFFT ON AMD64CLONING A HARD DRIVECONFIGURING AND USING KVM-QEMUUSING COUCHDBINSTALLING COUCHDB ON SLACKWARENGW100 MY OS AND EDXS/LSENGW100 - MY OSASTERISK FILTER APPLICATIONCISCO ROUTER CONFIGURATIONAASTRA 411 XML APPLICATIONSPA941 PHONEBOOKSPEEDTOUCH 780 DOCUMENTATIONAASTRA CONTACT LIST XML APPLICATIONAVR32 OS FOR NGW100ASTERISK SOUND INJECTION APPLICATIONNGW100 - DIFFERENT PROBLEMS AND SOLUTIONSAASTRA PRIME RATE XML APPLICATIONSPEEDTOUCH 780 CONFIGURATIONUSING COUCHDB WITH PHPAVR32 ASSEMBLY TIPAP7000 AND NGW100 ARCHITECTUREAASTRA WEATHER XML APPLICATIONNGW100 - GETTING STARTEDAASTRA ALI XML APPLICATION

STACK FRAME AND THE RED ZONE (X86_64)

2014-03-18

after days, and days, and days of troubleshooting odd problems I had in my homebrew x86_64 OS, I found out that it was caused by my C compiler. After spending all these years arguing with everyone that it is easier to make a hobby OS in pure assembly, I decided to make this OS with asm and C, and I just proved myself that C is evil! Seriously, C is not evil but it does hide a lot of things that makes it hard to know what your OS does.

So after disassembling all my C code and inspecting the assembly code, I found this:

55 push rbp 4889E5 mov rbp,rsp 48897DE8 mov [rbp-0x18],rdi 488975E0 mov [rbp-0x20],rsi 488955D8 mov [rbp-0x28],rdx C745FC00000000 mov dword [rbp-0x4],0x0 C9 leave C3 ret

Notice how the function never decreases the stack pointer? Arguments are passed below the stack pointer. Can you image how insane that is???? What would happen if an interrupt would trigger while in that function? The correct code would be:

55 push rbp 4889E5 mov rbp,rsp 4883EC28 ---> sub rsp,byte +0x28 <--- 48897DE8 mov [rbp-0x18],rdi 488975E0 mov [rbp-0x20],rsi 488955D8 mov [rbp-0x28],rdx C745FC00000000 mov dword [rbp-0x4],0x0 C9 leave C3 ret

It turns out that this behavior is normal according to the amd64 ABI. There is a thing called the "red zone". The red zone is a 128 bytes buffer that is guaranteed to be untouched by interrupt handlers (I'm not sure how though). To quote the ABI:

The 128-byte area beyond the location pointed to by %rsp is considered to be reserved and shall not be modified by signal or interrupt handlers. Therefore, functions may use this area for temporary data that is not needed across function calls. In particular, leaf functions may use this area for their entire stack frame, rather than adjusting the stack pointer in the prologue and epilogue. This area is known as the red zone.

So my solution was to just disable that damn red-zone with the gcc flag "-mno-red-zone". I'm guessing that the compiler does that to improve performances because it assumes that your code will be running in ring-3, so when an interrupt occurs, the stack will change because the handler will run in ring-0. Yeah sure, it will improve performances because there is one less instruction in the code, but I think that's a huge assumption to make. It definitely isn't the case when you are writing kernel code anyway.