update.c revision 5b59e4ca2abcd17b3a91b5fd099d17f8200d2a86
* Note: the logical computation for this is * (st_value1 - st_value2) * However, that is only correct if the address type is smaller * than a pointer. Writing it this way makes it immune to the * class (32 or 64-bit) of the linker. * Scan the sorted symbols, and issue warnings if there are any duplicate * values in the list. We only do this if -zverbose is set, or we are * running with LD_DEBUG defined * ofl - Output file descriptor * ldynsym - Pointer to start of .SUNW_ldynsym section that the * sort section indexes reference. * symsort - Pointer to start of .SUNW_dynsymsort or .SUNW_dyntlssort * n - # of indices in symsort array * secname - Name of the symsort section. * If the symsort section contains indexes to more than one * symbol with the same address value, a warning is issued. /* Nothing to do if -zverbose or LD_DEBUG are not active */ }
else {
/* Not a dup. Move reference up */ * Build and update any output symbol tables. Here we work on all the symbol * tables at once to reduce the duplication of symbol and string manipulation. * Symbols and their associated strings are copied from the read-only input * file images to the output image and their values and index's updated in the * There are several places in this function where we wish * to insert a symbol index to the combined .SUNW_ldynsym/.dynsym * symbol table into one of the two sort sections (.SUNW_dynsymsort * or .SUNW_dyntlssort), if that symbol has the right attributes. * This macro is used to generate the necessary code from a single * _sdp, _sym, _type - As per DYNSORT_COUNT. See _libld.h * _sym_ndx - Index that _sym will have in the combined * .SUNW_ldynsym/.dynsym symbol table. Word *
symndx;
/* Symbol index (for relocation use) */ Word ssndx;
/* global index into sorted_syms */ Word scndx;
/* scoped index into sorted_syms */ * Initialize pointers to the symbol table entries and the symbol * table strings. Skip the first symbol entry and the first string * table byte. Note that if we are not generating any output symbol * tables we must still generate and update an internal copies so * that the relocation phase has the correct information. * If we are also constructing a .SUNW_ldynsym section * to contain local function symbols, then set it up too. * If there is a SUNW_ldynsym, then there may also * be a .SUNW_dynsymsort and/or .SUNW_dyntlssort * sections, used to collect indices of function * and data symbols sorted by address order. * Initialize the hash table. * symndx is the symbol index to be used for relocation processing. It * points to the relevant symtab's (.dynsym or .symtab) symbol ndx. * If we have version definitions initialize the version symbol index * table. There is one entry for each symbol which contains the symbols * If syminfo section exists be prepared to fill it in. * Setup our string tables. * Put output file name to the first .symtab and .SUNW_ldynsym symbol. /* Scoped symbols get filled in global loop below */ * If we are to display GOT summary information, then allocate * the buffer to 'cache' the GOT symbols into now. * Traverse the program headers. Determine the last executable segment * and the last data segment so that we can update etext and edata. If * we have empty segments (reservations) record them for setting _end. * 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. * Assign .sunwdata1 information * If we are generating a .symtab collect all the local symbols, * assigning a new virtual address or displacement (value). * Check that we have local symbols to process. If the user * has indicated scoping then scan the global symbols also * looking for entries from this file to reduce to locals. * 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. * 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 */ * 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. * First, determine whether any .init or .fini sections exist. If these * sections exist when 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. * Assign .lbss information for use with updating LCOMMON symbols. * Assign .tlsbss information for use with updating COMMON symbols. * Assign .SUNWbss information for use with updating COMMON symbols. * Traverse the internal symbol table updating information and * 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 output image. * Only needed symbols will be copied to the * 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 .sunwdata1. * A partial initialized global symbol within a shared * object goes to .sunwbss. * 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 * 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. * 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 this symbol descriptor, as its boundto * element will need updating after the .dynamic * section has been created. Flag whether this * reference is lazy loadable, and if a direct * binding is to be established. * 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 necesssary to * prevent external direct bindings. * This definition exists within the object * being created. Flag whether it is necessary * to prevent external direct bindings. * Indicate that this symbol is acting as an * If external bindings are allowed, or this is * a translator symbol, indicate the binding, * and a direct binding if necessary. * If this is a translator, the symbols * boundto element will indicate the * dependency to which it should resolve * rather than itself. Save this info * for updating after the .dynamic * section has been created. * 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 its 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 /* 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. * Create and set up the DT_POSFLAG_1 entry here if required. * The following DT_* entries do not apply to relocatable objects. * 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. * 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. * Ensure that we wrote the right number of entries. If not, * we either miscounted in make_dynamic(), or we did something wrong * Build the version definition section * 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. * Build the version needed section * Traverse the shared object list looking for dependencies that have * versions defined within them. * If version needed definitions were specified in * a mapfile ($VERSION=*) then record those * Traverse the version index list recording * each version as a needed dependency. * 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. * Record association on string table section and use the * `info' field to indicate the number of entries in this * 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()). * Note. it may be necessary to update the `e_flags' field in the * machine dependent section. * Perform move table expansion. *((
unsigned long long *)
taddr) =
* Should never come here since this is already * checked at sunwmove_preprocess(). * Determine the index of the symbol table that will be referenced by * the relocation entries. * update sh_link and mv pointer for updating move table. * Update symbol entry index * Scan through the SHT_GROUP output sections. Update their * 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++) {
* Perform a sanity check that the section index * stored in the SHT_GROUP section is valid * for the file it came from. * If the referenced section didn't make it to the * output file - just zero out the entry. * 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: * o 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. * o 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. * o 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 * 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, * just remember where the program header is. * It's actual values will be assigned after * update_osym() has completed and the symbol * table addresses have been udpated. * 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 * If this is an empty segment declaration, it will occur after * all other loadable segments, make sure the previous segment * doesn't overlap. We do not do the check if we are generating 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 PT_SUNWBSS, set alignment * 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 a segment size symbol is required (specified via a * mapfile) update its 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 * (presumably from a map file) 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, 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 a PT_SUNWDTRACE phdr, update it now with the address of * the symbol. It's only now been updated via update_sym(). * Take permisions of the segment the symbol is associated with. * Update the GROUP sections. * Build any output headers, version information, dynamic structure and * 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'.