Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Position-independent code
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
{{short description|Machine instruction code that executes properly regardless of where in memory it resides}} {{redirect|PIC code|"presubscribed interexchange carrier code"|Carrier access code}} {{Use dmy dates|date=February 2020|cs1-dates=y}} {{Use list-defined references|date=January 2022}} In [[computing]], '''position-independent code'''<ref name="Intel_iRMX"/> ('''PIC'''<ref name="Intel_iRMX"/>) or '''position-independent executable''' ('''PIE''')<ref name="RedHat_PIE"/> is a body of [[machine code]] that executes properly regardless of its [[memory address]].{{efn|This allows each process using a shared copy to see it at a different virtual address.}} PIC is commonly used for [[shared library|shared libraries]], so that the same library code can be loaded at a location in each program's address space where it does not overlap with other memory in use by, for example, other shared libraries. PIC was also used on older computer systems that lacked an [[Memory management unit|MMU]],<ref name="Levine_1999_CH8"/> so that the [[operating system]] could keep applications away from each other even within the single [[address space]] of an MMU-less system. Position-independent code can be executed at any memory address without modification. This differs from absolute code,<ref name="Intel_iRMX"/> which must be loaded at a specific location to function correctly,<ref name="Intel_iRMX"/> and [[load-time locatable]] (LTL) code,<ref name="Intel_iRMX"/> in which a [[Linker (computing)|linker]] or [[Loader (computing)|program loader]] modifies a program before execution, so it can be run only from a particular memory location.<ref name="Intel_iRMX"/> The latter terms are sometimes referred to as ''position-dependent code''.<ref>{{cite web |url=https://docs.oracle.com/cd/E26505_01/html/E26506/glmqp.html |title=Position-Independent Code |publisher=[[Oracle]] |quote=The code within a dynamic executable is typically position-dependent, and is tied to a fixed address in memory.}}</ref> Generating position-independent code is often the default behavior for [[compiler]]s, but they may place restrictions on the use of some language features, such as disallowing use of absolute addresses (position-independent code has to use [[relative address]]ing). Instructions that refer directly to specific memory addresses sometimes execute faster, and replacing them with equivalent relative-addressing instructions may result in slightly slower execution, although modern processors make the difference practically negligible.<ref name="Gabert_2004"/> == History == In early computers such as the [[IBM 701]]<ref name="IBM_1952_701"/> (29 April 1952) or the [[UNIVAC I]] (31 March 1951) code was not position-independent: each program was built to load into and run from a particular address. Those early computers did not have an operating system and were not multitasking-capable. Programs were loaded into main storage (or even stored on magnetic drum for execution directly from there) and run one at a time. In such an operational context, position-independent code was not necessary. Even on [[base and bounds]]{{efn|name="NB_BNB"}} systems such as the [[CDC 6600]], the [[GE-600 series|GE 625]] and the [[UNIVAC 1107]], once the OS loaded code into a job's storage, it could only run from the relative address at which it was loaded. [[Burroughs Corporation|Burroughs]] introduced a [[Memory segmentation|segmented]] system, the [[B5000]] (1961), in which programs addressed segments indirectly via control words on the [[call stack|stack]] or in the program reference table (PRT); a shared segment could be addressed via different PRT locations in different processes. Similarly, on the later [[B6500]], all segment references were via positions in a [[stack frame]]. The [[IBM System/360 architecture|IBM System/360]] (7 April 1964) was designed with [[IBM System/360 architecture#Addressing|truncated addressing]] similar to that of the [[UNIVAC III]],<ref name="Sperry_1962"/> with code position independence in mind. In truncated addressing, memory addresses are calculated from a ''base register'' and an offset. At the beginning of a program, the programmer must establish ''addressability'' by loading a base register; normally, the programmer also informs the assembler with a ''USING'' pseudo-op. The programmer can load the base register from a register known to contain the entry point address, typically R15, or can use the [https://en.wikibooks.org/wiki/360_Assembly/360_Instructions/BALR BALR (Branch And Link, Register form)] instruction (with a R2 Value of 0) to store the next sequential instruction's address into the base register, which was then coded explicitly or implicitly in each instruction that referred to a storage location within the program. Multiple base registers could be used, for code or for data. Such instructions require less memory because they do not have to hold a full 24, 31, 32, or 64 bit address (4 or 8 bytes), but instead a base register number (encoded in 4 bits) and a 12βbit address offset (encoded in 12 bits), requiring only two bytes. This programming technique is standard on IBM S/360 type systems. It has been in use through to today's IBM System/z. When coding in assembly language, the programmer has to establish addressability for the program as described above and also use other base registers for dynamically allocated storage. Compilers automatically take care of this kind of addressing. IBM's early operating system [[DOS/360]] (1966) was not using virtual storage (since the early models of System S/360 did not support it), but it did have the ability to place programs to an arbitrary (or automatically chosen) storage location during loading via the PHASE name,* [[Job_Control_Language|JCL (Job Control Language)]] statement. So, on S/360 systems without virtual storage, a program could be loaded at any storage location, but this required a contiguous memory area large enough to hold that program. Sometimes [[Fragmentation (computing)|memory fragmentation]] would occur from loading and unloading differently sized modules. Virtual storage - by design - does not have that limitation. While DOS/360 and [[OS/360]] did not support PIC, transient [[Supervisor Call instruction#OS/360 and Successor System SVCs|SVC routines]] in OS/360 could not contain relocatable address constants and could run in any of the transient areas without [[relocation (computing) | relocation]]. IBM first introduced virtual storage on [[IBM System/360 Model 67|IBM System/360 model 67]] in (1965) to support IBM's first multi-tasking operating and time-sharing operating system TSS/360. Later versions of DOS/360 (DOS/VS etc.) and later IBM operating systems all utilized virtual storage. Truncated addressing remained as part of the base architecture, and still advantageous when multiple modules must be loaded into the same virtual address space. By way of comparison, on early [[Memory segmentation|segmented]] systems such as [[Burroughs MCP]] on the [[Burroughs large systems|Burroughs B5000]] (1961) and [[Multics]] (1964), and on paging systems such as IBM [[TSS (operating system)|TSS/360]] (1967){{efn|name="NB_TSS"}}, code was also inherently position-independent, since subroutine virtual addresses in a program were located in private data external to the code, e.g., program reference table, linkage segment, prototype section. The invention of dynamic address translation (the function provided by an [[Memory management unit|MMU]]) originally reduced the need for position-independent code because every process could have its own independent [[address space]] (range of addresses). However, multiple simultaneous jobs using the same code created a waste of physical memory. If two jobs run entirely identical programs, dynamic address translation provides a solution by allowing the system simply to map two different jobs' address 32K to the same bytes of real memory, containing the single copy of the program. Different programs may share common code. For example, the payroll program and the accounts receivable program may both contain an identical sort subroutine. A shared module (a shared library is a form of shared module) gets loaded once and mapped into the two address spaces. == SunOS 4.x and ELF == Procedure calls inside a shared library are typically made through small procedure linkage table (PLT) [[method stub|stub]]s, which then call the definitive function. This notably allows a shared library to inherit certain function calls from previously loaded libraries rather than using its own versions.<ref name="sunos 4.x">{{cite conference |url=https://www.cs.cornell.edu/courses/cs414/2001FA/sharedlib.pdf |title=Shared Libraries in SunOS |first1=Robert A. |last1=Gingell |first2=Meng |last2=Lee |first3=Xuong T. |last3=Dang |first4=Mary S. |last4=Weeks |conference=1987 Summer USENIX Technical Conference and Exhibition |pages=131β146}}</ref> Data references from position-independent code are usually made indirectly, through [[Global Offset Table]]s (GOTs), which store the addresses of all accessed [[global variable]]s. There is one GOT per compilation unit or object module, and it is located at a fixed offset from the code (although this offset is not known until the library is [[Library linking|linked]]). When a [[Linker (computing)|linker]] links modules to create a shared library, it merges the GOTs and sets the final offsets in code. It is not necessary to adjust the offsets when loading the shared library later.<ref name="sunos 4.x" /> Position-independent code that accesses global data does so by fetching the address for the global variable from its entry in the GOT. As the GOT is at a fixed offset from the code, the offset between the address of a given instruction in the code and the address of a GOT entry for a given global variable is also fixed, so that the offset does not need to be changed depending on the address at which the position-independent code is loaded. An instruction that fetches the GOT entry for a global variable would use an [[addressing mode]] that contains an offset relative to some instruction in the code; this might be a [[addressing mode#PC-relative 2|PC-relative]] addressing mode if the [[instruction set architecture]] supports it, or a [[addressing mode#Base plus offset, and variations|register-relative]] addressing mode, with functions loading that register with the address of an instruction in the [[function prologue]].<ref name="sunos 4.x" /><ref>{{cite book |title=System V Application Binary Interface Motorola 68000 Processor Family Supplement |date=1990 |url=https://people.debian.org/~glaubitz/m68k-sysv-abi.pdf |pages=3{{hyp}}32-3{{hyp}}35 |publisher=Prentice-Hall |isbn=0-13-877663-6}}</ref><ref>{{cite book |title=System V Application Binary Interface i386 Architecture Processor Supplement |edition=Fourth |url=https://www.sco.com/developers/devspecs/abi386-4.pdf |pages=3{{hyp}}35-3{{hyp}}39}}</ref><ref>{{cite book |title=System V Application Binary Interface AMD64 Architecture Processor Supplement (With LP64 and ILP32 Programming Models) Version 1.0 |url=https://cs61.seas.harvard.edu/site/2022/pdf/x86-64-abi-20210928.pdf |date=September 28, 2021}}</ref> == Windows DLLs == {{main|Dynamic-link library}} {{More citations needed section|date=April 2018}} [[Dynamic-link library|Dynamic-link libraries]] (DLLs) in [[Microsoft Windows]] use variant E8 of the CALL instruction (Call near, relative, displacement relative to next instruction). These instructions do not need modification when the DLL is loaded. Some global variables (e.g. arrays of string literals, virtual function tables) are expected to contain an address of an object in data section respectively in code section of the dynamic library; therefore, the stored address in the global variable must be updated to reflect the address where the DLL was loaded to. The dynamic loader calculates the address referred to by a global variable and stores the value in such global variable; this triggers copy-on-write of a memory page containing such global variable. Pages with code and pages with global variables that do not contain pointers to code or global data remain shared between processes. This operation must be done in any OS that can load a dynamic library at arbitrary address. In Windows Vista and later versions of Windows, the [[Relocation (computing)|relocation]] of DLLs and executables is done by the kernel memory manager, which shares the relocated binaries across multiple processes. Images are always relocated from their preferred base addresses, achieving [[address space layout randomization]] (ASLR).<ref name="Microsoft_Win"/> Versions of Windows prior to Vista require that system DLLs be [[prelink]]ed at non-conflicting fixed addresses at the link time in order to avoid runtime relocation of images. Runtime relocation in these older versions of Windows is performed by the DLL loader within the context of each process, and the resulting relocated portions of each image can no longer be shared between processes. The handling of DLLs in Windows differs from the earlier [[OS/2]] procedure it derives from. OS/2 presents a third alternative and attempts to load DLLs that are not position-independent into a dedicated "shared arena" in memory, and maps them once they are loaded. All users of the DLL are able to use the same in-memory copy. == Multics == In [[Multics]] each procedure conceptually{{efn|name="NB_REASON"}} has a code segment and a linkage segment.<ref>{{cite book | title = The Multics system; an examination of its structure | first = Elliott Irving | last = Organick | author-link = Elliott Organick | year = 1972 | isbn = 9780262150125 | lccn = 78157477 | publisher = [[MIT Press]] }} </ref> <ref>{{cite journal | journal = [[Communications of the ACM]] | volume = 11 | number = 5 | title = Virtual Memory, Processes, and Sharing in Multics | first1 = Robert C. | last1 = Daley | first2 = Jack B | last2 = Dennis | authorlink2 = Jack B. Dennis | pages = 306β312 | date = May 1968 | publisher = [[Association for Computing Machinery]] | doi = 10.1145/363095.363139 | url = https://multicians.org/daley-dennis.html | access-date = July 21, 2024 }} </ref> The code segment contains only code and the linkage section serves as a template for a new linkage segment. Pointer register 4 (PR4) points to the linkage segment of the procedure. A call to a procedure saves PR4 in the stack before loading it with a pointer to the callee's linkage segment. The procedure call uses an indirect pointer pair<ref name="Honeywell_1982"/> with a flag to cause a trap on the first call so that the dynamic linkage mechanism can add the new procedure and its linkage segment to the Known Segment Table (KST), construct a new linkage segment, put their segment numbers in the caller's linkage section and reset the flag in the indirect pointer pair. == TSS == In IBM S/360 Time Sharing System (TSS/360 and TSS/370) each procedure may have a read-only public CSECT and a writable private Prototype Section (PSECT). A caller loads a V-constant for the routine into General Register 15 (GR15) and copies an R-constant for the routine's PSECT into the 19th word of the save area pointed to be GR13.<ref name="IBM_1978_TSS"/> The Dynamic Loader<ref name="IBM_1971_360"/> does not load program pages or resolve address constants until the first page fault. == {{Anchor|PIE}}Position-independent executables == {{See also|Address space layout randomization}} ''Position-independent executables'' (PIE) are executable binaries made entirely from position-independent code. While some systems only run PIC executables, there are other reasons they are used. PIE binaries are used in some [[Security-focused operating system|security-focused]] [[Linux]] distributions to allow [[PaX]] or [[Exec Shield]] to use [[address space layout randomization]] (ASLR) to prevent attackers from knowing where existing executable code is during a security attack using [[security exploit|exploits]] that rely on knowing the offset of the executable code in the binary, such as [[return-to-libc attack]]s. (The official Linux kernel since 2.6.12 of 2005 has a weaker ASLR that also works with PIE. It is weak in that randomness is applied to whole ELF file units.)<ref>{{cite web |last1=Lettieri |first1=G |title=Address Space Layout Randomization |url=https://lettieri.iet.unipi.it/hacking/aslr-pie.pdf}}</ref> Apple's [[macOS]] and [[iOS]] fully support PIE executables as of versions 10.7 and 4.3, respectively; a warning is issued when non-PIE iOS executables are submitted for approval to Apple's App Store but there's no hard requirement yet {{when|date=July 2020}} and non-PIE applications are not rejected.<ref name="Non-PIE"/><ref name="iOS"/> [[OpenBSD]] has PIE enabled by default on most architectures since OpenBSD 5.3, released on 1 May 2013.<ref name="OpenBSD_2013"/> Support for PIE in [[statically linked]] binaries, such as the executables in <code>[[/bin]]</code> and <code>/sbin</code> directories, was added near the end of 2014.<ref name="Fedora_2014"/> openSUSE added PIE as a default in 2015-02. Beginning with [[Fedora (operating system)|Fedora]] 23, Fedora maintainers decided to build packages with PIE enabled as the default.<ref name="Fedora"/> [[Ubuntu (operating system)|Ubuntu]] [[Ubuntu version history#Ubuntu 17.10 (Artful Aardvark)|17.10]] has PIE enabled by default across all architectures.<ref name="Ubuntu"/> [[Gentoo Linux|Gentoo]]'s new profiles now support PIE by default.<ref name="gentoo-pie"/> Around July 2017, [[Debian]] enabled PIE by default.<ref name="Liang_2017"/> [[Android (operating system)|Android]] enabled support for PIEs in [[Android Jelly Bean|Jelly Bean]]<ref name="Android_1-4"/> and removed non-PIE linker support in [[Android Lollipop|Lollipop]].<ref name="Android_5"/> == See also == {{Portal|Computer programming}} * [[Dynamic linker]] * [[Object file]] * [[Code segment]] == Notes == {{Notelist|refs= {{efn|name="NB_TSS"|While TSS/360 supported shared PIC, that was not true of all paging systems}} {{efn|name="NB_BNB"|But a separate copy of the code was loaded for each job.}} {{efn|name="NB_REASON"|There are some technical deviations for performance reasons that are beyond the scope of this article.}} }} == References == {{Reflist|refs= <ref name="RedHat_PIE">{{cite web |url=https://access.redhat.com/blogs/766093/posts/1975793 |title=Position Independent Executables (PIE)}}</ref> <ref name="Sperry_1962">{{cite manual |title=Reference Manual UNIVAC III Data Processing System |id=UT-2488 |date=1962 |url=http://www.bitsavers.org/pdf/univac/univac3/UT-2488_UNIVACIII_ref_Jun62.pdf |publisher=[[Sperry Rand Corporation]]}}</ref> <ref name="Levine_1999_CH8">{{cite book |author-last=Levine |author-first=John R. |author-link=John R. Levine |title=Linkers and Loaders |date=2000 |orig-date=October 1999 |edition=1 |publisher=[[Morgan Kaufmann]] |series=The Morgan Kaufmann Series in Software Engineering and Programming |location=San Francisco, USA |isbn=1-55860-496-0 |id={{ISBN|978-1-55860-496-4}} |oclc=42413382 |chapter=Chapter 8: Loading and overlays |chapter-url=https://archive.today/20130103082119/http://www.iecc.com/linker/linker08.html<!-- https://web.archive.org/web/20120216090547/http://darcs.olsner.se/Linker/linker-book/linker08.html --> |pages=170{{ndash}}171 |url=https://www.iecc.com/linker/ |access-date=2020-01-12 |url-status=live |archive-url=https://archive.today/20121205032107/http://www.iecc.com/linker/ |archive-date=2012-12-05}} Code: [https://archive.today/20200114225034/https://linker.iecc.com/code.html][ftp://ftp.iecc.com/pub/linker/]{{dead link|date=May 2025|bot=medic}}{{cbignore|bot=medic}} Errata: [https://linker.iecc.com/<!-- https://archive.today/20200114224817/https://linker.iecc.com/ 2020-01-14 -->]</ref> <ref name="Gabert_2004">{{cite web |title=Position Independent Code internals |author-first=Alexander |author-last=Gabert |date=January 2004 |work=[[Hardened Gentoo]] |url=http://www.gentoo.org/proj/en/hardened/pic-internals.xml |access-date=2009-12-03 |quote=[β¦] direct non-PIC-aware addressing is always cheaper (read: faster) than PIC addressing. [β¦]}}</ref> <ref name="Microsoft_Win">{{cite web |url=https://view.officeapps.live.com/op/view.aspx?src=http%3A%2F%2Fdownload.microsoft.com%2Fdownload%2F9%2Fc%2F5%2F9c5b2167-8017-4bae-9fde-d599bac8184a%2FMemMgt.docx |title=Advances in Memory Management for Windows |website=View.officeapps.live.com |access-date=2017-06-23}}</ref> <ref name="Non-PIE">{{cite web |url=https://stackoverflow.com/questions/16455416/non-pie-binary-the-executable-project-name-is-not-a-position-independent-exe|title=iphone - Non-PIE Binary - The executable 'project name' is not a Position Independent Executable. - Stack Overflow |work=stackoverflow.com}}</ref> <ref name="iOS">{{cite web |url=https://developer.apple.com/library/ios/#qa/qa1788/_index.html |title=iOS Developer Library |work=apple.com}}</ref> <ref name="Fedora_2014">{{cite web |url=http://undeadly.org/cgi?action=article&sid=20141224204700&mode=expanded&count=0 |title=Heads Up: Snapshot Upgrades for Static PIE |date=2014-12-24 |access-date=2014-12-24}}</ref> <ref name="OpenBSD_2013">{{cite web |url=https://www.openbsd.org/53.html |title=OpenBSD 5.3 Release |date=2013-05-01 |access-date=2020-05-09}}</ref> <ref name="Fedora">{{cite web |url=http://fedoraproject.org/wiki/Changes/Harden_All_Packages |title=Changes/Harden All Packages - FedoraProject |website=fedoraproject.org}}</ref> <ref name="Ubuntu">{{cite web |url=https://lists.ubuntu.com/archives/ubuntu-devel/2017-June/039816.html |title=Ubuntu Foundations Team - Weekly Newsletter, 2017-06-15 |date=2017-06-15 |access-date=2017-06-17}}</ref> <ref name="Android_1-4">{{cite web |url=https://source.android.com/security/enhancements/enhancements41.html |title=Security Enhancements in Android 1.5 through 4.1 - Android Open Source Project |website=Android Open Source Project}}</ref> <ref name="Android_5">{{cite web |url=https://source.android.com/security/enhancements/enhancements50.html|title=Security Enhancements in Android 5.0 - Android Open Source Project |website=Android Open Source Project}}</ref> <ref name="Intel_iRMX">{{cite book |title=iRMX 86 Application Loader Reference Manual |publisher=[[Intel]] |url=http://bitsavers.informatik.uni-stuttgart.de/pdf/intel/iRMX/iRMX_86_Rev_6_Mar_1984/146196_Burst/iRMX_86_Application_Loader_Reference_Manual.pdf |chapter=Types of Object Code |pages=((1{{hyphen}}2, 1{{hyphen}}3)) |access-date=2017-08-21 |quote=[β¦] ''Absolute code'', and an absolute object module, is code that has been processed by LOC86 to run only at a specific location in memory. The [[Loader (computing)|Loader]] loads an absolute object module only into the specific location the module must occupy. ''Position-independent code'' (commonly referred to as PIC) differs from absolute code in that PIC can be loaded into any memory location. The advantage of PIC over absolute code is that PIC does not require you to reserve a specific block of memory. When the Loader loads PIC, it obtains [[iRMX 86]] memory segments from the pool of the calling task's job and loads the PIC into the segments. A restriction concerning PIC is that, as in the [[PL/M-86]] COMPACT model of segmentation [β¦], it can have only one code segment and one data segment, rather than letting the base addresses of these segments, and therefore the segments themselves, vary dynamically. This means that PIC programs are necessarily less than 64K bytes in length. PIC code can be produced by means of the BIND control of LINK86. ''[[Load-time locatable code]]'' (commonly referred to as LTL code) is the third form of object code. LTL code is similar to PIC in that LTL code can be loaded anywhere in memory. However, when loading LTL code, the Loader changes the base portion of pointers so that the pointers are independent of the initial contents of the registers in the microprocessor. Because of this fixup (adjustment of base addresses), LTL code can be used by tasks having more than one code segment or more than one data segment. This means that LTL programs may be more than 64K bytes in length. [[FORTRAN 86]] and [[Pascal 86]] automatically produce LTL code, even for short programs. LTL code can be produced by means of the BIND control of LINK86. [β¦]}}</ref> <ref name="gentoo-pie">{{cite web |url=https://www.gentoo.org/support/news-items/2017-11-30-new-17-profiles.html |title=New 17.0 profiles in the Gentoo repository |date=2017-11-30 |access-date=2017-12-10}}</ref> <ref name="IBM_1952_701">{{cite web |title=701 Announced |date=1952-04-29 |publisher=[[IBM]] |url=https://www.ibm.com/ibm/history/exhibits/701/701_announced.html |mode=cs2}}</ref> <ref name="Honeywell_1982">{{cite book |title=DPS/LEVEL 68 & DPS 8M MULTICS PROCESSOR MANUAL |id=AL39 |publisher=[[Honeywell Information Systems Inc.]] |pages=6β21 |section=Section 6 Virtual Address Formation |edition=Rev. 1 |date=1982 |url=http://bitsavers.org/pdf/honeywell/large_systems/multics/AL39-01B_MULTICS_Processor_Manual_Feb82.pdf |mode=cs2 |access-date=2023-03-25}}</ref> <ref name="IBM_1978_TSS">{{cite manual |title=IBM Time Sharing System Concepts and Facilities |id=GC28-2003-6 |section=Section 3: TSS for the: Svslcm Programmer |page=61 |date=April 1978 |edition=Seventh |url=http://bitsavers.org/pdf/ibm/360/tss/GC28-2003-6_Time_Sharing_System_Concepts_and_Facilities_Apr78.pdf}}</ref> <ref name="IBM_1971_360">{{cite manual |title=IBM System/360 Time Sharing System Dynamic Loader |id=GY28-2031-3 |date=September 1971 |url=http://bitsavers.org/pdf/ibm/360/tss/GY28-2031-3_Time_Sharing_System_Dynamic_Loader_PLM_Sep71.pdf |edition=Fourth}}</ref> <ref name="Liang_2017">{{cite web |author-last=Liang |author-first=Mudong |date=2017-08-08 |title=When did Debian decide to enabled PIE by default? |url=https://lists.debian.org/debian-user/2017/08/msg00456.html |access-date=2021-07-06 |website=debian.org}}</ref> }} * {{cite book |title=Nios II Processor Reference Guide |chapter=7.9.5. Linux Position-Independent Code |chapter-url=https://www.intel.com/content/www/us/en/docs/programmable/683836/current/linux-position-independent-code.html |publisher=[[Intel]]}} * {{cite book |title=Linker and Libraries Guide |chapter=Position-Independent Code |chapter-url=https://docs.oracle.com/cd/E26505_01/html/E26506/glmqp.html |publisher=[[Oracle Corporation|Oracle]]}} == External links == * [http://www.gentoo.org/proj/en/hardened/pic-guide.xml Introduction to Position Independent Code] * [http://www.gentoo.org/proj/en/hardened/pic-internals.xml Position Independent Code internals] * [https://web.archive.org/web/20150526050031/http://linux4u.jinr.ru/usoft/WWW/www_debian.org/Documentation/elf/node21.html Programming in Assembly Language with PIC] * [https://eklitzke.org/position-independent-executables The Curious Case of Position Independent Executables] {{application binary interface}} [[Category:Operating system technology]] [[Category:Computer libraries]] [[Category:Computer file formats]]
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)
Pages transcluded onto the current version of this page
(
help
)
:
Template:Anchor
(
edit
)
Template:Application binary interface
(
edit
)
Template:Cite book
(
edit
)
Template:Cite conference
(
edit
)
Template:Cite journal
(
edit
)
Template:Cite web
(
edit
)
Template:Efn
(
edit
)
Template:Main
(
edit
)
Template:More citations needed section
(
edit
)
Template:Notelist
(
edit
)
Template:Portal
(
edit
)
Template:Redirect
(
edit
)
Template:Reflist
(
edit
)
Template:See also
(
edit
)
Template:Short description
(
edit
)
Template:Use dmy dates
(
edit
)
Template:Use list-defined references
(
edit
)
Template:When
(
edit
)