update.c revision 98c080d502548e68bb9815459ea56e6ae282c430
2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 1988 AT&T 2N/A * All Rights Reserved 2N/A * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 2N/A * Use is subject to license terms. 2N/A * Update the new output file image, perform virtual address, offset and 2N/A * displacement calculations on the program headers and sections headers, 2N/A * and generate any new output section information. 2N/A * Comparison routine used by qsort() for sorting of the global symbol list 2N/A * based off of the hashbuckets the symbol will eventually be deposited in. 2N/A * Comparison routine used by qsort() for sorting of dyn[sym|tls]sort section 2N/A * indices based on the address of the symbols they reference. The 2N/A * use of the global dynsort_compare_syms variable is needed because 2N/A * we need to examine the symbols the indices reference. It is safe, because 2N/A * the linker is single threaded. 2N/A * Note: the logical computation for this is 2N/A * (st_value1 - st_value2) 2N/A * However, that is only correct if the address type is smaller 2N/A * than a pointer. Writing it this way makes it immune to the 2N/A * class (32 or 64-bit) of the linker. 2N/A * Scan the sorted symbols, and issue warnings if there are any duplicate 2N/A * values in the list. We only do this if -zverbose is set, or we are 2N/A * running with LD_DEBUG defined 2N/A * ofl - Output file descriptor 2N/A * ldynsym - Pointer to start of .SUNW_ldynsym section that the 2N/A * sort section indexes reference. 2N/A * symsort - Pointer to start of .SUNW_dynsymsort or .SUNW_dyntlssort 2N/A * n - # of indices in symsort array 2N/A * secname - Name of the symsort section. 2N/A * If the symsort section contains indexes to more than one 2N/A * symbol with the same address value, a warning is issued. 2N/A /* Nothing to do if -zverbose or LD_DEBUG are not active */ 2N/A }
else {
/* Not a dup. Move reference up */ 2N/A * Build and update any output symbol tables. Here we work on all the symbol 2N/A * tables at once to reduce the duplication of symbol and string manipulation. 2N/A * Symbols and their associated strings are copied from the read-only input 2N/A * file images to the output image and their values and index's updated in the 2N/A * There are several places in this function where we wish 2N/A * to insert a symbol index to the combined .SUNW_ldynsym/.dynsym 2N/A * symbol table into one of the two sort sections (.SUNW_dynsymsort 2N/A * or .SUNW_dyntlssort), if that symbol has the right attributes. 2N/A * This macro is used to generate the necessary code from a single 2N/A * _sdp, _sym, _type - As per DYNSORT_COUNT. See _libld.h 2N/A * _sym_ndx - Index that _sym will have in the combined 2N/A * .SUNW_ldynsym/.dynsym symbol table. 2N/A /* relocation use) */ 2N/A * Initialize pointers to the symbol table entries and the symbol 2N/A * table strings. Skip the first symbol entry and the first string 2N/A * table byte. Note that if we are not generating any output symbol 2N/A * tables we must still generate and update internal copies so 2N/A * that the relocation phase has the correct information. 2N/A * If we are also constructing a .SUNW_ldynsym section 2N/A * to contain local function symbols, then set it up too. 2N/A * If there is a SUNW_ldynsym, then there may also 2N/A * be a .SUNW_dynsymsort and/or .SUNW_dyntlssort 2N/A * sections, used to collect indices of function 2N/A * and data symbols sorted by address order. 2N/A * Initialize the hash table. 2N/A * symndx is the symbol index to be used for relocation processing. It 2N/A * points to the relevant symtab's (.dynsym or .symtab) symbol ndx. 2N/A * If we have version definitions initialize the version symbol index 2N/A * table. There is one entry for each symbol which contains the symbols 2N/A * If syminfo section exists be prepared to fill it in. 2N/A * Setup our string tables. 2N/A * Put output file name to the first .symtab and .SUNW_ldynsym symbol. 2N/A /* Scoped symbols get filled in global loop below */ 2N/A * If we are to display GOT summary information, then allocate 2N/A * the buffer to 'cache' the GOT symbols into now. 2N/A * Traverse the program headers. Determine the last executable segment 2N/A * and the last data segment so that we can update etext and edata. If 2N/A * we have empty segments (reservations) record them for setting _end. 2N/A * Generate a section symbol for each output section. * Generate the .shstrtab for this section. * Find the section index for our special symbols. * While we're here, determine whether a .init or .fini * Add local register symbols to the .dynsym. These are required as * DT_REGISTER .dynamic entries must have a symbol to reference. * Having traversed all the output segments, warn the user if the * traditional text or data segments don't exist. Otherwise from these * segments establish the values for `etext', `edata', `end', `END', * One of the segments must be of zero size. * If the last loadable segment is a read-only segment, * then the application which uses the symbol _end to * find the beginning of writable heap area may cause * segmentation violation. We adjust the value of the * _end to skip to the next page boundary. * 6401812 System interface which returs beginning * When the above RFE is implemented, the changes below * could be changed in a better way. * If we're dealing with a memory reservation there are * no sections to establish an index for _end, so assign * Determine the last section for this segment. * Initialize the scoped symbol table entry point. This is for all * the global symbols that have been scoped to locals and will be * filled in during global symbol processing so that we don't have * to traverse the globals symbol hash array more than once. * If expanding partially expanded symbols under '-z nopartial', * If we are generating a .symtab collect all the local symbols, * assigning a new virtual address or displacement (value). * Assign a got offset if necessary. * Ignore any symbols that have been marked as invalid * during input processing. Providing these aren't used * for relocation they'll just be dropped from the * If the section that this symbol was associated * with has been discarded - then we discard * the local symbol along with it. * If this symbol is from a different file * than the input descriptor we are processing, * treat it as if it has FLG_SY_ISDISC set. * This happens when sloppy_comdat_reloc() * replaces a symbol to a discarded comdat section * with an equivalent symbol from a different * file. We only want to enter such a symbol * once --- as part of the file that actually * Generate an output symbol to represent this input * symbol. Even if the symbol table is to be stripped * we still need to update any local symbols that are * used during relocation. * Provided this isn't an unnamed register * symbol, update its name. * Not using symtab, but we do have ldynsym /* Add it to sort section if it qualifies */ }
else {
/* Not using symtab or ldynsym */ * If this symbol requires modifying to provide * for a relocation or move table update, make * Update the symbols contents if necessary. * If we are expanding the locally bound partially * initialized symbols, then update the address here. * If this isn't an UNDEF symbol (ie. an input section * is associated), update the symbols value and index. * TLS symbols are relative to * If entering the symbol in both the symtab and the * ldynsym, then the one in symtab needs to be * copied to ldynsym. If it is only in the ldynsym, * then the code above already set it up and we have * nothing more to do here. /* Add it to sort section if it qualifies */ * If this input file has undergone object to symbol * capabilities conversion, supply any new capabilities symbols. * These symbols are copies of the original global symbols, and * follow the existing local symbols that are supplied from this * input file (which are identified with a preceding STT_FILE). * Update the symbols value. * Update the symbols section index. * Two special symbols are `_init' and `_fini'. If these are supplied * by crti.o then they are used to represent the total concatenation of * the `.init' and `.fini' sections. * Determine whether any .init or .fini sections exist. If these * sections exist and a dynamic object is being built, but no `_init' * or `_fini' symbols are found, then the user is probably building * this object directly from ld(1) rather than using a compiler driver * that provides the symbols via crt's. * If the .init or .fini section exist, and their associated symbols, * determine the size of the sections and updated the symbols value * Assign .bss information for use with updating COMMON symbols. * For amd64 target, assign .lbss information for use * with updating LCOMMON symbols. * Assign .tlsbss information for use with updating COMMON symbols. * Traverse the internal symbol table updating global symbol information * Ignore any symbols that have been marked as invalid during * input processing. Providing these aren't used for * relocation, they will be dropped from the output image. * Only needed symbols are copied to the output symbol table. * Note - expand the COMMON symbols here because an address * must be assigned to them in the same order that space was * calculated in sym_validate(). If this ordering isn't * followed differing alignment requirements can throw us all * The expanded .bss global symbol is handled here as well. * The actual adding entries into the symbol table still occurs * below in hashbucket order. * An expanded symbol goes to a special .data section * prepared for that purpose (ofl->ofl_isparexpn). * Assign COMMON allocations to .bss. * Otherwise leave it as is. * TLS symbols are relative to the TLS segment. * Make sure this COMMON symbol is returned to the same * binding as was defined in the original relocatable * If this is a dynamic object then add any local capabilities symbols. * Indicate that this is a capabilities symbol. * Note, that this identification only provides * information regarding the symbol that is * visible from elfdump(1) -y. The association * of a symbol to its capabilities is derived * from a .SUNW_capinfo entry. * Assign a got offset if necessary. * If this symbol has been marked as being reduced to local * scope then it will have to be placed in the scoped portion * of the .symtab. Retain the appropriate index for use in * version symbol indexing and relocation. * Copy basic symbol and string information. * If we require to record version symbol indexes, update the * associated version symbol information for all defined * symbols. If a version definition is required any zero value * symbol indexes would have been flagged as undefined symbol * errors, however if we're just scoping these need to fall into * the base of global symbols. /* Use index of verneed record */ * If we are creating the .syminfo section then set per symbol * Identify a copy relocation symbol. * A reference is bound to a needed dependency. * Save the syminfo entry, so that when the * .dynamic section has been updated, a * DT_NEEDED entry can be associated * (see update_osyminfo()). * Flag that the symbol has a direct association * with the external reference (this is an old * tagging, that has no real effect by itself). * And flag whether this reference is lazy * Enable direct symbol bindings if: * - Symbol was identified with the DIRECT * - Symbol reference has been bound to a * dependency which was specified as * requiring direct bindings with -zdirect. * - All symbol references are required to * use direct bindings via -Bdirect. * If this symbol has been explicitly defined * as external, and remains unresolved, mark * If this symbol has been explicitly defined * to be a reference to a parent object, * indicate whether a direct binding should be * A filter definition. Although this symbol * can only be a stub, it might be necessary to * prevent external direct bindings. * An auxiliary filter definition. By nature, * this definition is direct, in that should the * filtee lookup fail, we'll fall back to this * object. It may still be necessary to * prevent external direct bindings. * This definition exists within the object * being created. Provide a default boundto * definition, which may be overridden later. * Indicate whether it is necessary to prevent * external direct bindings. * Indicate that this symbol is acting as an * If external bindings are allowed, indicate * the binding, and a direct binding if * Provide a default boundto definition, * which may be overridden later. * Indicate that this is a capabilities symbol. * Note, that this identification only provides * information regarding the symbol that is * visible from elfdump(1) -y. The association * of a symbol to its capabilities is derived * from a .SUNW_capinfo entry. * Note that the `sym' value is reset to be one of the new * symbol table entries. This symbol will be updated further * depending on the type of the symbol. Process the .symtab * first, followed by the .dynsym, thus the `sym' value will * remain as the .dynsym value when the .dynsym is present. * This ensures that any versioning symbols st_name value will * be appropriate for the string table used by version /* Add it to sort section if it qualifies */ * Provided this isn't an unnamed register symbol, * update the symbols name and hash value. * Add it to sort section if it qualifies. * The indexes in that section are relative to the * add the number of items in SUNW_ldynsym to the * If we have a weak data symbol for which we need the real * symbol also, save this processing until later. * The exception to this is if the weak/strong have PLT's * assigned to them. In that case we don't do the post-weak * processing because the PLT's must be maintained so that we * can do 'interpositioning' on both of the symbols. * assign new symbol value. * Undefined weak global, if we are generating a static * executable, output as an absolute zero. Otherwise * leave it as is, ld.so.1 will skip symbols of this * type (this technique allows applications and * libraries to test for the existence of a symbol as an * indication of the presence or absence of certain /* COMMONs have already been processed */ * This is (or was) a COMMON symbol which was * processed above - no processing * Make sure this undefined symbol is returned * to the same binding as was defined in the * original relocatable object reference. * In an executable, the new symbol value is the * old value (offset into defining section) plus * virtual address of defining section. In a * relocatable, the new value is the old value * plus the displacement of the section within * TLS symbols are relative to * Symbol bias for negative growing tables is * stored in symbol's value during * If a plt index has been assigned to an undefined function, * update the symbols value to the appropriate .plt address. * Finish updating the symbols. * Sym Update: if scoped local - set local binding * Sym Updated: If both the .symtab and .dynsym * are present then we've actually updated the information in * the .dynsym, therefore copy this same information to the * dynsym and ldynsym are distinct tables, so * we use indirection to access the right one * and the related extended section index array. * Now that all the symbols have been processed update any weak symbols * information (ie. copy all information except `st_name'). As both * symbols will be represented in the output, return the weak symbol to * If the symbol definition has been scoped then assign it to * be local, otherwise if it's from a shared object then we need * to maintain the binding of the original reference. * Now display GOT debugging information if required. * Update the section headers information. sh_info is * supposed to contain the offset at which the first * global symbol resides in the symbol table, while * sh_link contains the section index of the associated * Ensure that the expected number of symbols * were entered into the right spots: * - Scoped symbols in the right range * - Globals start at the right spot * (correct number of locals entered) * - The table is exactly filled * (correct number of globals entered) /* ldynsym has no globals, so give index one past the end */ * The ldynsym and dynsym must be adjacent. The * idea is that rtld should be able to start with * the ldynsym and march straight through the end * of dynsym, seeing them as a single symbol table, * despite the fact that they are in distinct sections. * Ensure that this happened correctly. * Note that I use ldynsym_ndx here instead of the * computation I used to set the section size * (found in ldynsym_cnt). The two will agree, unless * we somehow miscounted symbols or failed to insert them * all. Using ldynsym_ndx here catches that error in * addition to checking for adjacency. * The presence of .SUNW_ldynsym means that there may be * associated sort sections, one for regular symbols * and the other for TLS. Each sort section needs the * - Section header link references .SUNW_ldynsym * - Should have received the expected # of items * - Sorted by increasing address * Build the dynamic section. * This routine must be maintained in parallel with make_dynamic() * Relocatable objects can be built with -r and -dy to trigger the * creation of a .dynamic section. This model is used to create kernel * device drivers. The .dynamic section provides a subset of userland * .dynamic entries, typically entries such as DT_NEEDED and DT_RUNPATH. * Within a dynamic object, any .dynamic string references are to the * .dynstr table. Within a relocatable object, these strings can reside * Create and set up the DT_POSFLAG_1 entry here if required. * Note, the shdr is set and used in the ofl->ofl_osldynsym case * We have arranged for the .SUNW_ldynsym data to be * immediately in front of the .dynsym data. * This means that you could start at the top * of .SUNW_ldynsym and see the data for both tables * without a break. This is the view we want to * provide for DT_SUNW_SYMTAB, which is why we * add the lengths together. * Reserve the DT_CHECKSUM entry. Its value will be filled in * after the complete image is built. * Versioning sections: DT_VERDEF and DT_VERNEED. * The Solaris ld does not produce DT_VERSYM, but the GNU ld * does, in order to support their style of versioning, which * - The top bit of the 16-bit Versym index is * not part of the version, but is interpreted * - External (SHN_UNDEF) symbols can have non-zero * Versym values, which specify versions in * referenced objects, via the Verneed section. * - The vna_other field of the Vernaux structures * found in the Verneed section are not zero as * with Solaris, but instead contain the version * index to be used by Versym indices to reference * the given external version. * The Solaris ld, rtld, and elfdump programs all interpret the * presence of DT_VERSYM as meaning that GNU versioning rules * apply to the given file. If DT_VERSYM is not present, * then Solaris versioning rules apply. If we should ever need * to change our ld so that it does issue DT_VERSYM, then * this rule for detecting GNU versioning will no longer work. * In that case, we will have to invent a way to explicitly * specify the style of versioning in use, perhaps via a * new dynamic entry named something like DT_SUNW_VERSIONSTYLE, * where the d_un.d_val value specifies which style is to be * Only the presence of this entry is used in this * implementation, not the value stored. * If -Bdirect was specified, but some NODIRECT symbols were specified * via a mapfile, or -znodirect was used on the command line, then * clear the DF_1_DIRECT flag. The resultant object will use per-symbol * direct bindings rather than be enabled for global direct bindings. * If any no-direct bindings exist within this object, set the * DF_1_NODIRECT flag. ld(1) recognizes this flag when processing * dependencies, and performs extra work to ensure that no direct * bindings are established to the no-direct symbols that exist * within these dependencies. * Ensure that we wrote the right number of entries. If not, we either * miscounted in make_dynamic(), or we did something wrong in this * Build the version definition section * Determine which string table to use. * Traverse the version descriptors and update the version structures * to point to the dynstr name in preparation for building the version * Create a new string table entry to represent the base * version name (there is no corresponding symbol for * Traverse the version descriptors and update the version section to * reflect each version and its associated dependencies. * Traverse this versions dependency list generating the * appropriate version dependency entries. * Record the versions auxiliary array offset and the associated * Record the next versions offset and update the version * pointer. Remember the previous version offset as the very * last structures next pointer should be null. * Record the string table association with the version definition * section, and the symbol table associated with the version symbol * table (the actual contents of the version symbol table are filled * in during symbol update). * The version definition sections `info' field is used to indicate the * number of entries in this section. * Finish the version symbol index section * Record the symbol table associated with the version symbol table. * The contents of the version symbol table are filled in during * Build the version needed section * Determine which string table is appropriate. * Traverse the shared object list looking for dependencies that have * versions defined within them. * Traverse the version index list recording * each version as a needed dependency. * If version A inherits version B, then * B is implicit in A. It suffices for ld.so.1 * to verify A at runtime and skip B. The * version normalization process sets the INFO * flag for the versions we want ld.so.1 to * Record the versions auxiliary array offset and * the associated dependency count. * Record the next versions offset and update the version * pointer. Remember the previous version offset as the very * last structures next pointer should be null. * Use sh_link to record the associated string table section, and * sh_info to indicate the number of entries contained in the section. * Update syminfo section. * Update any references with the index into the dynamic table. * Update any filtee references with the index into the dynamic table. * Display debugging information about section. * Build the output elf header. * If an entry point symbol has already been established (refer * sym_validate()) simply update the elf header entry point with the * symbols value. If no entry point is defined it will have been filled * with the start address of the first section within the text segment * (refer update_outfile()). * When generating a relocatable object under -z symbolcap, set the * e_machine to be generic, and remove any e_flags. Input relocatable * objects may identify alternative e_machine (m.machplus) and e_flags * values. However, the functions within the created output object * are selected at runtime using the capabilities mechanism, which * supersedes the e-machine and e_flags information. Therefore, * e_machine and e_flag values are not propagated to the output object, * as these values might prevent the kernel from loading the object * before the runtime linker gets control. * Note. it may be necessary to update the e_flags field in the * machine dependent section. * Perform move table expansion. * Update the target address based upon the move entry size. * This size was validated in ld_process_move(). * Determine the index of the symbol table that will be referenced by * Update sh_link of the Move section, and point to the new Move data. * Update symbol entry index * Scan through the SHT_GROUP output sections. Update their sh_link/sh_info * fields as well as the section contents. * Since input GROUP sections always create unique * output GROUP sections - we know there is only one * Scan through the group data section and update * all of the links to new values. for (i =
1; i <
grpcnt; i++) {
* If the referenced section didn't make it to the * output file - just zero out the entry. /* If leaving an extra hole at the end, zero it */ * Update capabilities information. * If string table capabilities exist, then the associated string must be * translated into an offset into the string table. * Determine which symbol table or string table is appropriate. * If symbol capabilities exist, set the sh_link field of the .SUNW_cap * section to the .SUNW_capinfo section. * If there are capability strings to process, set the sh_info * field of the .SUNW_cap section to the associated string table, and * proceed to process any CA_SUNW_PLAT entries. * Determine whether an object capability identifier, or object * Update the .SUNW_capinfo, and possibly the .SUNW_capchain sections. * Determine which symbol table is appropriate. * Update the .SUNW_capinfo sh_link to point to the appropriate symbol * table section. If we're creating a dynamic object, the * .SUNW_capinfo sh_info is updated to point to the .SUNW_capchain * Establish the data for each section. The first element of each * section defines the section's version number. * Traverse all capabilities families. Each member has a .SUNW_capinfo * assignment. The .SUNW_capinfo entry differs for relocatable objects * Family lead: CAPINFO_SUNW_GLOB lead symbol index * Family lead alias: CAPINFO_SUNW_GLOB lead symbol index * Family member: .SUNW_cap index lead symbol index * Family lead: CAPINFO_SUNW_GLOB .SUNW_capchain index * Family lead alias: CAPINFO_SUNW_GLOB .SUNW_capchain index * Family member: .SUNW_cap index lead symbol index * The ELF_C_GROUP field identifies a capabilities symbol. Lead * capability symbols, and lead capability aliases are identified by * a CAPINFO_SUNW_GLOB group identifier. For family members, the * ELF_C_GROUP provides an index to the associate capabilities group * (i.e, an index into the SUNW_cap section that defines a group). * For relocatable objects, the ELF_C_SYM field identifies the lead * capability symbol. For the lead symbol itself, the .SUNW_capinfo * index is the same as the ELF_C_SYM value. For lead alias symbols, * the .SUNW_capinfo index differs from the ELF_C_SYM value. This * differentiation of CAPINFO_SUNW_GLOB symbols allows ld(1) to * identify, and propagate lead alias symbols. For example, the lead * capability symbol memcpy() would have the ELF_C_SYM for memcpy(), * and the lead alias _memcpy() would also have the ELF_C_SYM for * For dynamic objects, both a lead capability symbol, and alias symbol * would have a ELF_C_SYM value that represents the same capability * chain index. The capability chain allows ld.so.1 to traverse a * family chain for a given lead symbol, and select the most appropriate * family member. The .SUNW_capchain array contains a series of symbol * indexes for each family member: * chaincap[n] chaincap[n + 1] chaincap[n + 2] chaincap[n + x] * foo() ndx foo%x() ndx foo%y() ndx 0 * For family members, the ELF_C_SYM value associates the capability * members with their family lead symbol. This association, although * unused within a dynamic object, allows ld(1) to identify, and * propagate family members when processing relocatable objects. * For a dynamic object, identify this lead symbol, and * point it to the head of a capability chain. Set the * head of the capability chain to the same lead symbol. * For a relocatable object, identify this lead symbol, * and set the lead symbol index to itself. * Gather any lead symbol aliases. * For a dynamic object, identify this lead * alias symbol, and point it to the same * capability chain index as the lead symbol. * For a relocatable object, identify this lead * alias symbol, and set the lead symbol index * Gather the family members. * Identify the members capability group, and the lead * symbol of the family this symbol is a member of. * For a dynamic object, set the next capability * chain to point to this family member. * Any chain of family members is terminated with a 0 element. * Translate the shdr->sh_{link, info} from its input section value to that * of the corresponding shdr->sh_{link, info} output section value. * Don't translate the special section numbers. * Does this output section translate back to an input file. If not * then there is no translation to do. In this case we will assume that * if sh_link has a value, it's the right value. * Sanity check to make sure that the sh_{link, info} value * is within range for the input file. * Follow the link to the input section. * Having created all of the necessary sections, segments, and associated * headers, fill in the program headers and update any other data in the * output image. Some general rules: * - If an interpreter is required always generate a PT_PHDR entry as * well. It is this entry that triggers the kernel into passing the * interpreter an aux vector instead of just a file descriptor. * - When generating an image that will be interpreted (ie. a dynamic * executable, a shared object, or a static executable that has been * provided with an interpreter - weird, but possible), make the initial * loadable segment include both the ehdr and phdr[]. Both of these * tables are used by the interpreter therefore it seems more intuitive * to explicitly defined them as part of the mapped image rather than * relying on page rounding by the interpreter to allow their access. * - When generating a static image that does not require an interpreter * have the first loadable segment indicate the address of the first * .section as the start address (things like /kernel/unix and ufsboot * Initialize the starting address for the first segment. Executables * have different starting addresses depending upon the target ABI, * where as shared objects have a starting address of 0. If this is * a 64-bit executable that is being constructed to run in a restricted * address space, use an alternative origin that will provide more free * address space for the the eventual process. * Loop through the segment descriptors and pick out what we need. * If an interpreter is required generate a PT_INTERP and * PT_PHDR program header entry. The PT_PHDR entry describes * the program header table itself. This information will be * passed via the aux vector to the interpreter (ld.so.1). * The program header array is actually part of the first * loadable segment (and the PT_PHDR entry is the first entry), * therefore its virtual address isn't known until the first * loadable segment is processed. * If we are creating a PT_SUNWDTRACE segment, remember where * the program header is. The header values are assigned after * update_osym() has completed and the symbol table addresses * generate the PT_SUNWCAP header. Note, as this comes before * the first loadable segment, we don't yet know its real * virtual address. This is updated later. * As the dynamic program header occurs after the loadable * headers in the segment descriptor table, all the address * information for the .dynamic output section will have been * As the unwind (.eh_frame_hdr) program header occurs after * the loadable headers in the segment descriptor table, all * the address information for the .eh_frame output section * will have been figured out by now. * The sunwstack program is used to convey non-default * flags for the process stack. Only emit it if it would * As the TLS program header occurs after the loadable * headers in the segment descriptor table, all the address * information for the .tls output section will have been * Scan the output sections that have contributed TLS. * Remember the first and last so as to determine the * TLS memory size requirement. Remember the last * progbits section to determine the TLS data * contribution, which determines the TLS program * Determine the initialized TLS data size. This * address range is from the start of the TLS segment * to the end of the last piece of initialized data. * Determine the total TLS memory size. This includes * all TLS data and TLS uninitialized data. This * address range is from the start of the TLS segment * to the memory address of the last piece of * If this is an empty segment declaration, it will occur after * all other loadable segments. As empty segments can be * defined with fixed addresses, make sure that no loadable * segments overlap. This might occur as the object evolves * and the loadable segments grow, thus encroaching upon an * existing segment reservation. * Segments are only created for dynamic objects, thus this * checking can be skipped when building a relocatable object. for (i = 0; i <
phdrndx -
1; i++) {
* Having processed any of the special program headers any * remaining headers will be built to express individual * segments. Segments are only built if they have output * section descriptors associated with them (ie. some form of * input section has been matched to this segment). * Determine the segments offset and size from the section * information provided from elf_update(). * Allow for multiple NOBITS sections. * If this is the first loadable segment of a dynamic object, * or an interpreter has been specified (a static object built * with an interpreter will still be given a PT_HDR entry), then * compensate for the elf header and program header array. Both * of these are actually part of the loadable segment as they * may be inspected by the interpreter. Adjust the segments * size and offset accordingly. * If segment size symbols are required (specified via a * mapfile) update their value. * If no file content has been assigned to this segment (it * only contains no-bits sections), then reset the offset for * If a virtual address has been specified for this segment * from a mapfile use it and make sure the previous segment * does not run into this segment. * Adjust the address offset and p_align if needed. * If an interpreter is required set the virtual address of the * PT_PHDR program header now that we know the virtual address * of the loadable segment that contains it. Update the * PT_SUNWCAP header similarly. * Finally, if we're creating a dynamic object * (or a static object in which an interpreter * is specified) update the vaddr to reflect * the address of the first section within this * If the DF_1_NOHDR flag was set, and an * interpreter is being generated, the PT_PHDR * will not be part of any loadable segment. * Ensure the ELF entry point defaults to zero. Typically, this * value is overridden in update_oehdr() to one of the standard * entry points. Historically, this default was set to the * address of first executable section, but this has since been * found to be more confusing than it is helpful. * Traverse the output section descriptors for this segment so * that we can update the section headers addresses. We've * calculated the virtual address of the initial section within * this segment, so each successive section can be calculated * based on their offsets from each other. * Establish the virtual address of the end of the last section * in this segment so that the next segments offset can be * Output sections for this segment complete. Adjust the * virtual offset for the last sections size, and make sure we * haven't exceeded any maximum segment length specification. * Update any new output sections. When building the initial output * image, a number of sections were created but left uninitialized (eg. * .dynsym, .dynstr, .symtab, .symtab, etc.). Here we update these * sections with the appropriate data. Other sections may still be * modified via reloc_process(). * Copy the interpreter name into the .interp section. * Update the .shstrtab, .strtab and .dynstr sections. * Build any output symbol tables, the symbols information is copied * and updated into the new output image. * If we have an PT_INTERP phdr, update it now from the associated * If we have a PT_SUNWDTRACE phdr, update it now with the address of * the symbol. It's only now been updated via update_sym(). * Take permissions from the segment that the symbol is * If we have a PT_SUNWCAP phdr, update it now from the associated * Update the GROUP sections. * Build any output headers, version information, dynamic structure and * Update capabilities information if required. * Sanity test: the first and last data byte of a string table * Emit Strtab diagnostics. * Initialize the section headers string table index within the elf * If the STRTAB section index doesn't fit into * e_shstrndx, then we store it in 'shdr[0].st_link'.