Object Files: Difference between revisions

use appropriate template
[unchecked revision][unchecked revision]
(use appropriate template)
 
(16 intermediate revisions by 3 users not shown)
Line 1:
{{You}}
 
Object files basically consist of compiled and assembled code, data, and all the additional information necessary to make their content usable. In the process of building an operating system, you will use a lot of object files. While for common development tasks you do not need to know their exact details, when you want to create or use one with various specifics, the details can be very important.
 
Line 12 ⟶ 14:
* loading, where the address stubs are replaced by the loader with the actual memory locations that the code will reside within the process' memory.
 
== ObjectsObject files, executablesexecutable files and librarieslibrary files ==
Whereas Wikipedia considers executables to be a subset of object files, on the basis that both contain object code rather than a binary image, there are significant differences. In some systems, they are a completely different format (COFF vs PE), or they have different fields (ELF program/section headers). The key difference is that in executables, the full object code of the program is present (save for whatever may be in shared libraries, as explained below), while object files are only the object code for the specific module that they were generated from. This means that non-executable files do not contain loadable code.
 
As stated earlier, this does not necessarily mean that the 'executable' file is the actual binary image that is executed; in most modern systems, that is produced in the loading step, during which the address locations are resolved. In mostmany cases, executable files still contain object code, not pure machine code, and the address locations may not be resolved until loading, but they ''do'' include all of the statically-linked code for the working program. Some linkers (such as '''[[LD|ld''']], the Unix/Linux linker, which is invoked implicitly by GCC when generating an executable) have the option (of - or even default to), as [[LD|ld]] does - resolving the addresses at link time, but even in this case, the executable files generated usually contain additional information to facilitate the loading process - e.g., a separate read-only data section, a definition of the writable data area (sometimes called the ''[https://en.wikipedia.org/wiki/.bss .bss section]''), a section defining the stack area, etc. - and may have linkage information for using shared libraries.
 
A third type of object code file is a ''library file'', a file that contains elements used by several programs, and made available for general use. Most functions, variables, and other elements used by the majority of programs are held in libraries. Libraries differ from regular object files mainly in that (on most systems) they are arranged so that independent elements of the library can be extracted from the file by the linker, so that only the elements used by the program are included in the executable generated from them.
Line 55 ⟶ 57:
 
== Common errors ==
* '''Passing -i or -r to ld.''' There's actually a tutorial that does this. It does not work except for some limited cases, as it generates a file where relocations have not been applied at all.
* '''Assuming code and data are continuous.''' A pitfall when trying to make a PE file multiboot-compatible. A section is generally page-aligned (4k), but a PE file is sector-aligned (512b). So if a section is not multiple of 4k in size, relative addresses to the data section will be off by a multiple of 512 bytes as the gap has been removed from the binary. Worse, it is perfectly valid to have metadata sections between the various loadable sections, which can put addresses off.
* '''Loading as a flat binary.''' All executables that aren't flat binaries have a header up front. Blatantly loading a file and starting at the start will execute the header instead of your code. Again, there is a tutorial that tries to get away with this.