Jump Slot

Jump Slot Rating: 4,0/5 4762 reviews
  1. Jump Clothes Off
  2. Jackpot Jump Slot Machine
  3. Happy Jump Slot
  4. Jungle Jump Slot
  5. Jackpot Jump Slot Machine Wins
  6. Cars Slow Motion Jump Slot Car
Modified Aug 3/99

Slot online for free in demo mode with no download and no registration required and read the game's review before playing for real money. The company takes this lively pepper and uses it repeatedly as a theme for Jumpin’ Jalapenos slot machine, their five-reel, three-row penny slot game. Jumpin’ Jalapeno: Core Gameplay Jumpin’ Jalapenos is a penny slot with 30 paylines and a payback rate of 96.04 percent RTP. Carrera 63504 Speed Trap Battery Operated 1:43 Scale Slot Car Racing Track Set with Jump Ramp. 4.3 out of 5 stars.


Pat Beirne

Copyright Pat Beirne 1999
All rights reserved

Overview

In the old days, applications were build by compiling many .c files into.o files. These files often had inter-related references that weren't resolvedat compile time. The information on these references are stored withinthe .o files in areloc (relocation) object.

Later, at link time, the linker would merge all the .o files, buildinga table of where symbols are ultimately located. Then the linker wouldrun through the set of relocs, filling them in.

A reloc consists of three parts:

  • where in memory the fix is to be made
  • the symbol which is involved in the fix
  • an algorithm that the linker should use to create the fixup
The most interesting part of this paper is the latter element. The algorithmcan be as simple as 'use the symbol memory location; store it in binary'(R_386_32. Or it may be more complicated, such as 'calculatethe distance from here to the symbol, divide by 4, subtract 2 and add theresult to the 3 lower bytes' (R_ARM_PC26).

These relocs are scattered through the .o files, and are used at linktime create the correct binary executable file. Once all the relocs areresolved, the linker is pretty well done its job.

At least this is the way things used to work, in the days of staticlinking.

With the introduction of run-time linking, the designers of the ELFformat decided that relocs are a suitable entity to hold run-time resolutioninformation. So now we have executable files which still have relocs inthem, even after linking.

However, new algorithms are required to signal how these fixups areto be done. Hence the introduction of a new family of reloc numbers (i.e.algorithms)

Relocs and Memory Space

What is a reloc? Binary executables often need certain bits of informationfixed up before they execute. ELF binaries carry a list of relocs whichdescribe these fixups. Each reloc contains:
the address in the binary that is to get the fixup(offset)
the algorithm to calculate the fixup (type)
a symbol (string and object len)
At fixup time, the algorithm uses the offset & symbol, along withthe value currently in the file, to calculate a new value to be depositedinto memory. See Appendix B

One of the targets of the ELF binary system is a separation of codeand data. The code of apps and libraries is marked read-only andexecutable.The data is markedread-write, and not-executable.

The code is read-only so that multiple processes can use thecode, having loaded the code into memory only once. Each process has itsown page tables, mapping the code into its own memory. The code is nevermodified, and appears identical in each process space. Naturally, the codemust be position independent; each process can load the app into a differentaddress.

The code segment is allowed to contain constant pointers and strings(.rodata).

The data segment is read-write and is mapped into each processspace differently. [In Linux, each data segment is loaded from the samebase mmap, but it is markedcopy-on-write; after the first write,each process has its own copy of the data.] Therefore, relocs can onlypoint to the data segment.

This half-and-half nature of ELF binaries leads us to an interestingdesign point. Some of the relocs that we wish to make are in the data segment.These are easy to do: we can add relative offsets, or write absolute addresseswith no problem. But the fixups in the code area are more difficult. TheELF reloc design forces us to make the code relocs 'bounce off' an entryin the data area, known as the GOT (global offset table).

In other words, if code needs to refer to a global object, it insteadrefers to an entry in the GOT[], and at run-time, the GOT entry is fixed-upto point to the intended data. In this manner, the code space need neverbe fixed-up at run time. If the code needs to refer to a local object,it refers to it 'relative to the &GOT[0]'; this too is position independent.NOTE 1

If the code needs to jump to a subroutine in a different module, thelinker creates an array of jump-stubs, called the PLT (procedure linkuptable). These jump-stubs jump indirect, using an entry in the GOT[] toimplement the far call.

Finally, ELF implements run time linking by deferring function resolutionuntil the function is called. This means that calls to library functionsgo through a fixup process the first time that they are called.

The rest of this paper explains the operation of these concepts.

NOTE 1: Relative (GOTOFF) code is made 'relativeto the start of the GOT table'. Instead, it could have been made 'relativeto the load address of the module', which would have been cleaner in myopinion. But there are reasons that some architectures chose the former,so we'll stick with it.

Reloc Design

Relocs are used in many places in the design cycle:
  1. in .o files intended for executables
  2. in .o files intended for shared libraries
  3. in executables
  4. in shared libraries (.so files)
1) Object files need to be able to reference external symbols. In modernarchitectures, we can usually get away with
1-i) relative, from 'here' to a symbol (R_*_PC32), used forbranches
1-ii) abolute, to a symbol (R_*_32) NOTE 2

2) Object files which are going to be part of a library are a littledifferent. For one thing, they must be compiled as PIC code, using the-fpicflag. Next, there must be a distinction between local data/functions andglobal data/functions. Finally, relocs in the code/.rodata sections mustuse got-based relocs, because the code/.rodata area of the final libaryfile cannot be modified at run time. The relocs are:

in code:
2-i) reference to local symbol: use the relative distance from theGOT to the local symbol (R_*_GOTOFF); these relocs can exist inthe code area, because they will be fully resolved at link time
2-ii) reference to a global symbol: create an entry in the GOT andlet the run-time system deposit the symbol's address into the GOT for us(R_*_GOT32)
2-iii) In addition, relative calls to subroutiine (R_*_PC32)can be used.

in data:
2-iii) reference to symbol (R_*_32) [NOTE: symbols which areglobal have a reloc that references the symbol by name; symbols which arelocal can have a reloc that simply references the section number, and havea section-offset contained in the reloc. See NOTE 2]

3) Executables need to be able to refer to global data (such as errno)as if there is only one copy. ELF systems do this by copying global symbolsdown into the application .bss space. Then the executable and all the librariespoint to this single copy. To realize this, we need relocs:
3-i) reach into a library to a symbol and copy down the data into ourown .bss space (R_*_COPY)
3-ii) pointer to global data (R_*_GLOB_DAT)
3-iii) pointer to library function (R_*_JMP_SLOT)
Notice that all of these relocs must modifiy only the data sectionof the executable; the code section is read-only! All the relocs from the.o file have either been resolved, or mutated into one of the above 3.

4) Shared libraries are the most complex. By the time the library islinked, all the R_*_GOTOFF relocs (from the .o files) are resolved.
4-i) All the R_*_GOT32 relocs are resolved, pointing at GOTentries. At link time, these GOT entries get relocs of their own, pointingto the global data/function. (R_*_GLOB_DAT/R_*_JMP_SLOT respectively).
4-ii) There will be times when local data structures need to hold absolutepointers to local data. Put the module-relative address of the symbol inthe library; at run-time, add the module-load address to it (R_*_RELATIVE)
NOTE 3

Jump Clothes Off

Again, notice that all of these relocs must modifiy only the data sectionof the executable; the code section is read-only!

When the linker creates 3) and 4) above, the linker actually createscode and data that was not explicit in the .o files. There is a .plt sectioncreated in the code segment, which is an array of function stubs used tohandle the run-time resolution of library calls. There is a .got sectioncreated in the data segment, which holds pointers to global symbols. Bothof these synthetic sections are 'helpers' to the code segment, since thecode segment cannot be modified at run-time.

To make all this happen, the object files must contain information aboutwhether a symbol is global or local, function or data, and the object size.(The old a.out scheme did not require all this extra info)

NOTE 2 At this point, I'll mention that globalrelocs must neccessarily involve the three aspects of a reloc:

  • where in memory the reloc is to be made
  • the symbol involved in the reloc
  • the algorithm used to make the fixup.
However, if the symbol is local, and can be fixed in memory with respectto a memory 'section', the object file is allowed to drop the symbol name,and replace it with a section-plus-offset.

For instance, in this ARM code


The code on the 3rd line (the call) needs to be fixed up, but that'seasy, since it's a PC relative fixup.

If the .o file has no idea where .Lextern is, it must neccessarilycreate a reloc which refers to
symbol Lextern.


The word at .L3 needs a fixup as well. If the .o file can determinethe location of a local symbol, such as L2, then it is allowed to replacethe symbol with a section-plus-offset. The offset is stored in thereloc target address, and the section is an entry in the reloc symbol tableThis reduces the number of symbols in the symbol table, making run-timelinking easier.

NOTE 3 Notice that the R_*_GOTOFF and R_*_GOT32relocs include an offset from &GOT[0}, which is usually about halfwaythrough the module. The R_ARM_RELATIVE relocs, on the other hand, containsan offset from the beginning of the module. Why? Tradition.

Jump Tables

As much as possible, ELF dynamic linking defers the resolution of jump/calladdresses until the last minute. The technique is based on the followingconstraints.
  • The calling technique should not force a change in the assembly code producedfor apps; it MAY cause changes in the way assembly code is produced forpic-code (i.e. libraries)
  • The technique must be such that all executable areas must not be modifiedat run time; and any modified data areas must not be executed.
To do this, there are three steps involved in a typical far jump:
  1. start in the code
  2. go through the PLT
  3. using a pointer from the GOT
Machine[Before explaining how this works, I should tell you that the GOT entriesthat are used for PLT execution are preloaded to default addresses.]

1) In the code:This is typical code using the relative jump or call. The target is anentry in the PLT. Note that this call is identical to a normal call.

2) In the PLT: The PLT is a synthetic area, created by the linker. Itexists in both executables and libraries. It is an array of stubs, oneper imported function call.

On i386 architecture, this code looks like:A subroutine call to PLT[n+1] will result jumping indirect through GOT[n+3].When first invoked, GOT[n+3] points back to PLT[n+1]+6, which is the push/jmpsequence. Going through the PLT[0], the resolver uses the argument on thestack to determine 'n' and resolves the symbol 'n'. The resolver code thenrepairs GOT[n+3] to point directly at the target subroutine.

The first PLT entry is slightly different, and is used to form a trampolineto the fixup code.Flow is directed to the resolver routine. 'n' is already on the stack,and &GOT[1] gets added on the stack. This way the resolver (locatedin ld-linux.so.2) can determine which library is asking for its service.

3) In the GOT: The GOT (global offset table) contains helper pointersfor both PLT fixups and GOT fixup. The first 3 entries are special/reserved.The next M entries belong to the PLT fixups. The next D entries belongto various data fixups.

The GOT is a synthetic area, created by the linker. It exists in bothexecutables and libraries.

When the GOT is first set up, all the GOT entries relating to PLT fixupsare pointing to code back at PLT[0].

The special entries in the GOT are
GOT[0] = linked list pointer usedby the dyn-loader
GOT[1] = pointer to the reloctable for this module
GOT[2] = pointer to the fixup/resolvercode, located in the ld-linux.so.2 library
followed by
GOT[3] .... GOT[3+M] = indirectfunction call helpers, one per imported function
GOT[3+M+1] ...... GOT[end]= indirect pointers for global data references, one per imported global

Remember that each library and executable gets its own PLT and GOT array.

Memory & Load Addresses

In a typical Linux system, the addresses 0-3fff.ffff (3 gigs)are available for the user program space.

Exectuable binary files include header information that indicates aload address. Libraries, because they are position-independent, don't needa load address, but contain a 0 in this field.

i386Jackpot Jump Slot MachineJackpot inferno jump slot winners

The shared library design usually has the app loading first, then theloader notices that it need support, and loads the dyn-loader library (usually/lib/ld-linux.so.2) at 0x4000.0000. Other libraries are loaded after ld.so.1.You can see where libraries will load by using the utility ldd
ldd foo_app

There is a diagnostic case where the app is invoked by
/lib/ld-linux.so.2 foo_appfoo_arg ....
In this case, the ld-linux.so.2 is loaded as an app. Sinceit was built as a library, it tries to load at 0. [In ArmLinux, this isforbidden, so the kernel pushes it up to 0x1000.] Once ld-linux.so.2loads, it reads it argv[1] and loads the foo_app at itspreferred location (0x0800.0000). Other libraries are loaded up a the mmaparea. So, in this case, the user memory map appears as

Please, if you need more text, let me know: patb@corel.ca

Appendix A: Relocs in i386


Here is some analysis of the i386 design:

Intel

in .o files; these are the old relocs......

Happy Jump Slot


R_386_PC32determine the destinance from this memory location to the 'symbol',then add it to the value currently at this dword; deposit the result backinto the dword
These four were introduced with dynamic libraries; they are found onlyin .o files which are going to be part of a library (pic code):
R_386_PLT32create a new entry in the PLT[] and GOT[]
determine the distance from here to the PLT[] entry and store thatdistance as a dword at this location
at final link, rename the reloc to a R_386_JMP_SLOT, keeping the same'symbol' and point it at the GOT[] entry

Executable files that are built 'static' have no relocs in them. Theyrun standalone.

In executable files which are intended to run with shared libraries......
R_386_COPYread a string of bytes from the 'symbol' address and deposit a copyinto this location; the 'symbol' object has an intrinsic length
i.e. move initialized data from a library down into the app data space
Dynamic library files also have R_386_JMP_SLOT relocs, plus
this reloc is, in a sense, the complement of the R_386_COPY above
R_386_RELATIVEat dynamic link time, read the dword at this location, add it to therun-time start address of this module; deposit the result back into thisdword

Note that R_386_32 relocs can appear in libraries as well. These mustbe executed carefully!

R_386_COPY and R_386_GLOB_DATA can be considered complements ofeach other. Suppose you have a global data object defined in a dynamiclibrary. The library will have the binary version of the object in its.data space. When the application is built, the linker puts a R_386_COPYreloc in there to copy the data down to the application's .bss space. Inturn, the library never references the original global object; it referencesthe copy that is in the application data space, through a correspondingR_386_GLOB_DATA. Wierd, huh? After loading and copying, the original data(from the library) is never used; only the copy (in the app data space).

To make the whole dynamic linking operation happen, the linker introducesseveral 'synthetic' constructs into the target when you build an app ora library:
Jungle Jump Slotstruct Rel {
uint32 r_offset;
uint24 r_sym_index;
uint8 r_type;
};
enum for t_type {
R_386_32=1,
R_386_GOT32=3,
R_386_PLT32=4,
R_386_COPY=5,
R_386_GLOB_DAT=6,
R_386_JUMP_SLOT=7,
R_386_RELATIVE=8,
R_386_GOTOFF=9,
R_386_GOTPC=10
};

Here is an excerpt from the reloc list for my version of /usr/bin/dir
When the reloc algorithm is invoked, it has direct access to:
the reloc target location
the symbol name
and, indirectly, it has access to:
the data currently at the target location (sometimescalled the addend)
the object length, through the symbol description
The algorithm must make all its calculations based on these 4 piecesof data.

Some architectures, like the M68k use a different reloc, called Rela,which has one extra parameter, called an addend. This makes the relocs12 bytes each, instead of 8. The Rel is just as flexible (in my opinion:)

Jackpot Jump Slot Machine Wins

Example code

This appendix will show C code which triggers the new relocs.
Suppose we have this libary code:When the compiler builds the .o files, lines 1 and 2 are marked as needinga full 32 bit address; R_386_32 relocs are generated. But the address canbe determined locally, so the symbols can be dropped and offsets used instead.Lines 3 & 4 will also generate a R_386_32 reloc, requesting a fullabsolute address, to be associated with the symbols 'cPub' and 'fPub'.

Line 5 publishes a function foo() as a public symbol. Since it can becalled from outside, and it needs to be position independent (-fpic),it needs to generate a local reference to the GOT. Early in the prologin foo(), the compiler will generate something like:
mov &GOT[0], %ebx
so that the rest of the subroutine has a reference to &GOT[0] forfurther processing. Note that line 5 requires &GOT[0], which itselfrequires a reloc: R_386_GOTPC, meaning 'the distance from here tothe GOT'. This extra reloc is the overhead of each public function thatis compiled -fpic.

Line 6 will trigger a R_386_PLT32 reloc, using the symbol 'fPub'. Line7 also generates the same reloc, against the symbol 'fLocal'. (This relocwill disappear at the final link.)

Line 8 requires the address of a public object. This object locationhas to be flexible at run time, so a R_386_GOT32 reloc is used. Later,at link time, this will create an address slot in the GOT[].

Line 9 requires the 'contents of' the same object. The object contentsare fetched by using the address contained in the GOT[] entry. [Note thatcompiler is smart enough to use a single reloc to realize both line 8 andline 9]

Lines 10 & 11 require the address and contents of a local object.We don't know exactly where this object is going to be a run time, butwe do know that it is local, and we can state its position relative tothe &GOT[0]. So a pair of R_386_GOTOFF relocs are generated. [Again,the compiler may merge lines 10 and 11 into a single reloc, but it didn'twhen I built this example.]

[Because of the structure of the linker, full name resolution isn'tchecked until a link is made with an executable. In other words, if yourlibrary has unresolved references, you won't find out about it until youtry to make an app using your library.]

To summarize, the .o file contains the following relocs:
in the data section:and in the code section:

Later, when the linker is called for the final link stage,the relocs at line 1 & 2 will mutate into a R_386_RELATIVE. The reloctarget location is loaded with the offset of the information. At run-time,the dyn-linker will add the module address to the offset and deposit theresult back into the reloc target. The symbol is not used in this case.

Lines 3 & 4 remain as R_386_32 relocs, and will ask the dyn-linkerfor the full 32 bit absolute address to be deposited into the reloc target.

Cars Slow Motion Jump Slot Car

The reloc triggered by line 5 is fixed up fully, and does not appearin the library.

The reloc in line 6 will cause the linker to add a PLT entry, and acorresponding GOT entry. The latter gets a R_386_JUMP_SLOT reloc, usingthe symbol 'fPub'. [The code generated at line 6 appears to be a subroutinecall into the PLT entry.]

The reloc at line 7 can be fully resolved by the final linker stage,so it is transformed into a direct call to fLocal().

The reloc at line 8 and 9 will cause the linker to add a GOT entry,which will hold &cPub. The GOT entry gets marked with a R_386_GLOB_DATreloc, asking the dyn-linker for the full 32 bit abolute address.

The relocs at line 10 & 11 can be fully resolved at final link time.They turn into 'find the data at &GOT[0] plus this offset', sono relocis required.

As you can see, the 10 relocs in the .o file turn into 4 in the library.Also, the PLT gets a new entry, and the GOT gets two new entries.


Now suppose we have an executable which references the library:When the .o file is created, there is a R_386_PC32 generated for 'fPub'and a R_386_32 generated for the 'cPub'.

When the executable is created, the R_386_PC32 from line 1 will causean entry in the PLT, and the code will call into the PLT. At the same time,the linker will create an entry in the GOT, which the PLT will jump through.The GOT entry will get a R_386_JUMP_SLOT reloc, using the symbol 'fPub'.

The data reference in line 2 will cause a local copy of the global cPubto be created in the data space of the app. The data reference at line2 is changed to point to this new global data, and the reloc is resolved.This new global gets a R_386_COPY reloc, using the symbol 'cPub'. The symbolhas certain properties, including the fact that references data, and thatit has a length of 1 byte. At run time, the dyn-linker will find the symbolcPub in one of the libraries and copy the 1 byte down from the libraryinto the app data space. The dyn-linker will then publish that latter addressas the address of 'cPub'.

Request for comments

I think the above is exhaustive for the i386. Please let me know if I missedsomething, or if the presentation should be changed. PatBeirne