What is the difference in bytecode like Java bytecode and machine code files and executables like ELF?

What are the differences between executable bytecode files, such as Java class files, Parrot bytecode files or CLR files, and machine code executables such as ELF, Mach-O, and PE.

What are the distinguishing differences between them?

for example, the .text region in the ELF structure is equal to that part of the class file?

or they all have headers, but ELF and PE headers contain Architecture, but the class file is not

Java class file Java class file

Elf file ELF File

PE file PE file

+4
source share
2 answers

The byte code, as the emulsion noted, is an intermediate step, right before compilation into machine code. Since the last step is loading time (and often runtime, as is the case with Just-In-Time (JIT) compilation, the bytecode is architecture independent: the runtime (CLR for .net or JVM for Java) is responsible for matching the byte code code with their basic representation of machine code.

For comparison, native code (Windows: PE, PE32 +, OS X / iOS: Mach-O, Linux / Android / etc: ELF) is compiled code suitable for a specific architecture (Android / iOS: ARM, in most cases: Intel 32-bit (i386) or 64-bit). They are all very similar, but still require partitions (or in the Mach-O "Boot Commands" section) to configure the memory structure of the executable file, since it becomes a process (Old DOS supports the ".com" format, which was an unhandled memory image) . In all of the above, you can roughly say the following:

  • Sections with the symbol "." are created by the compiler and are "standard" or are expected to have default behavior
    • The executable contains a section of the main code, usually called "text" or ".text". This is proprietary code that can work in a specific architecture.
    • Strings are stored in a separate section. They are used for hardcoded output (what you print), as well as for character names.
    • Symbols are what the linker uses to combine the executable with its libraries (Windows: DLL, Linux / Android: shared objects, OS X / iOS: .dylibs or frameworks) are stored in a separate section. Usually, there is also a “PLT” (Procedure Binding Table), which allows the compiler to simply put in the stub functions that you call (printf, open, etc.) that the linker can include when loading the executable.
    • The import table (in Windows. In ELF, this is the DYNAMIC section; in OS X, this is the LC_LOAD_LIBRARY command) is used to declare additional libraries. If they are not found when downloading the executable file, the download is not performed and you cannot start it.
    • Export table (for libraries / dylibs / etc.) - these are symbols that the library can export (or on Windows, even in .exe), for communication with others.
    • Constants are usually found in what you see as ".rodata".

Hope this helps. In fact, your question was vague.

TG

+11
source

The bytecode is a halfway step. Therefore, the Java compiler (javac) will turn the source code into byte code. Machine code is the next step when a computer takes byte code, turns it into machine code (which can be read by a computer), and then runs your program by reading machine code. Computers cannot directly read the source code, nor can compilers directly translate the machine code. You will need halfway for the programs to work.

+6
source

All Articles