sections.c revision d579eb63ae5b8d8c65917b341e8c19a4df710606
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 1988 AT&T
* All Rights Reserved
*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Module sections. Initialize special sections
*/
#include <string.h>
#include <strings.h>
#include <stdio.h>
#include <link.h>
#include <debug.h>
#include "msg.h"
#include "_libld.h"
/*
* If -zignore is in effect, scan all input sections to see if there are any
* which haven't been referenced (and hence can be discarded). If sections are
* to be discarded, rescan the output relocations and the symbol table and
* remove the relocations and symbol entries that are no longer required.
*
* Note: It's possible that a section which is being discarded has contributed
* to the GOT table or the PLT table. However, we can't at this point
* eliminate the corresponding entries. This is because there could well
* be other sections referencing those same entries, but we don't have
* the infrastructure to determine this. So, keep the PLT and GOT
* entries in the table in case someone wants them.
* Note: The section to be affected needs to be allocatable.
* So even if -zignore is in effect, if the section is not allocatable,
* we do not eliminate it.
*/
static uintptr_t
{
int allow_ldynsym;
/*
* Diagnose (-D unused) a completely unreferenced file.
*/
continue;
/*
* Before scanning the whole symbol table to determine if
* symbols should be discard - quickly (relatively) scan the
* sections to determine if any are to be discarded.
*/
discard = 0;
discard++;
break;
}
}
}
/*
* No sections are to be 'ignored'
*/
continue;
/*
* We know that we have discarded sections. Scan the symbol
* table for this file to determine if symbols need to be
* discarded that are associated with the 'ignored' sections.
*/
/* LINTED - only used for assert() */
int err;
/*
* If the whole file is being eliminated, remove the
* local file symbol, and any COMMON symbols (which
* aren't associated with a section) provided they
* haven't been referenced by a relocation.
*/
ofl->ofl_locscnt--;
if (allow_ldynsym &&
ldynsym_symtype[type]) {
ofl->ofl_dynlocscnt--;
err = st_delstring(
/* Remove from sort section? */
type, --);
}
}
continue;
}
/*
* Skip any undefined, reserved section symbols, already
* discarded or eliminated symbols. Also skip any
* symbols that don't originate from a section, or
* aren't defined from the file being examined.
*/
(type == STT_SECTION) ||
continue;
/*
* If any references were made against the section
* the symbol is being defined in - skip it.
*/
continue;
/*
* Finish processing any local symbols.
*/
if ((ofl->ofl_flags1 &
FLG_OF1_REDLSYM) == 0) {
ofl->ofl_locscnt--;
if (allow_ldynsym &&
ldynsym_symtype[type]) {
ofl->ofl_dynlocscnt--;
err = st_delstring(
/* Remove from sort section? */
type, --);
}
}
}
continue;
}
/*
* Global symbols can only be eliminated when an objects
* interfaces (versioning/scoping) is defined.
*/
ofl->ofl_scopecnt--;
ofl->ofl_elimcnt++;
if (allow_ldynsym &&
ldynsym_symtype[type]) {
ofl->ofl_dynscopecnt--;
err = st_delstring(
/* Remove from sort section? */
}
}
continue;
}
}
}
return (1);
/*
* Scan all output relocations searching for those against discarded or
* ignored sections. If one is found, decrement the total outrel count.
*/
/* LINTED */
if ((_isdesc == 0) ||
continue;
continue;
else
if (!(flags & FLG_REL_PLT))
ofl->ofl_reloccntsub++;
ofl->ofl_relocrelcnt--;
}
}
return (1);
}
/*
* Allocate Elf_Data, Shdr, and Is_desc structures for a new
* section.
*
* entry:
* ofl - Output file descriptor
* shtype - SHT_ type code for section.
* shname - String giving the name for the new section.
* entcnt - # of items contained in the data part of the new section.
* This value is multiplied against the known element size
* for the section type to determine the size of the data
* area for the section. It is only meaningful in cases where
* the section type has a non-zero element size. In other cases,
* the caller must set the size fields in the *ret_data and
* *ret_shdr structs manually.
* ret_isec, ret_shdr, ret_data - Address of pointers to
* receive address of newly allocated structs.
*
* exit:
* On error, returns S_ERROR. On success, returns (1), and the
* ret_ pointers have been updated to point at the new structures,
* which has been filled in. To finish the task, the caller must
* update any fields within the supplied descriptors that differ
* from its needs, and then call ld_place_section().
*/
static uintptr_t
{
typedef struct sec_info {
} SEC_INFO_T;
const SEC_INFO_T *sec_info;
/*
* For each type of section, we have a distinct set of
* SEC_INFO_T values. This macro defines a static structure
* containing those values and generates code to set the sec_info
* pointer to refer to it. The pointer in sec_info remains valid
* outside of the declaration scope because the info_s struct is static.
*/
{ \
sh_entsize}; \
}
switch (shtype) {
case SHT_PROGBITS:
/*
* SHT_PROGBITS sections contain are used for many
* different sections. Alignments and flags differ.
* Some have a standard entsize, and others don't.
* We set some defaults here, but there is no expectation
* that they are correct or complete for any specific
* purpose. The caller must provide the correct values.
*/
break;
case SHT_SYMTAB:
break;
case SHT_DYNSYM:
case SHT_SUNW_LDYNSYM:
break;
case SHT_STRTAB:
/*
* A string table may or may not be allocable, depending
* on context, so we leave that flag unset and leave it to
* the caller to add it if necessary.
*
* String tables do not have a standard entsize, so
* we set it to 0.
*/
break;
case SHT_RELA:
/*
* Relocations with an addend (Everything except 32-bit X86).
* The caller is expected to set all section header flags.
*/
break;
case SHT_REL:
/*
* Relocations without an addend (32-bit X86 only).
* The caller is expected to set all section header flags.
*/
break;
case SHT_HASH:
case SHT_SUNW_symsort:
case SHT_SUNW_tlssort:
break;
case SHT_DYNAMIC:
/*
* A dynamic section may or may not be allocable, depending
* on context, so we leave that flag unset and leave it to
* the caller to add it if necessary.
*/
break;
case SHT_NOBITS:
/*
* SHT_NOBITS is used for BSS-type sections. The size and
* alignment depend on the specific use and must be adjusted
* by the caller.
*/
break;
case SHT_INIT_ARRAY:
case SHT_FINI_ARRAY:
case SHT_PREINIT_ARRAY:
sizeof (Addr))
break;
case SHT_SYMTAB_SHNDX:
/*
* Note that these sections are created to be associated
* with both symtab and dynsym symbol tables. However, they
* are non-allocable in all cases, because the runtime
* linker has no need for this information. It is purely
* informational, used by elfdump(1), debuggers, etc.
*/
break;
case SHT_SUNW_cap:
break;
case SHT_SUNW_move:
/*
* The sh_info field of the SHT_*_syminfo section points
* to the header index of the associated .dynamic section,
* so we also set SHF_INFO_LINK.
*/
break;
case SHT_SUNW_syminfo:
/*
* The sh_info field of the SHT_*_syminfo section points
* to the header index of the associated .dynamic section,
* so we also set SHF_INFO_LINK.
*/
break;
case SHT_SUNW_verneed:
case SHT_SUNW_verdef:
/*
* The info for verneed and versym happen to be the same.
* The entries in these sections are not of uniform size,
* so we set the entsize to 0.
*/
break;
case SHT_SUNW_versym:
sizeof (Versym));
break;
default:
/* Should not happen: fcn called with unknown section type */
assert(0);
return (S_ERROR);
}
/*
* Allocate and initialize the Elf_Data structure.
*/
return (S_ERROR);
/*
* Allocate and initialize the Shdr structure.
*/
return (S_ERROR);
/*
* Allocate and initialize the Is_desc structure.
*/
return (S_ERROR);
return (1);
}
/*
* Build a .bss section for allocation of tentative definitions. Any `static'
* .bss definitions would have been associated to their own .bss sections and
* thus collected from the input files. `global' .bss definitions are tagged
* as COMMON and do not cause any associated .bss section elements to be
* generated. Here we add up all these COMMON symbols and generate the .bss
* section required to represent them.
*/
{
uint_t ident;
/*
* Allocate header structs. We will set the name ourselves below,
* and there is no entcnt for a BSS. So, the shname and entcnt
* arguments are 0.
*/
return (S_ERROR);
ident = M_ID_TLSBSS;
ident = M_ID_BSS;
ident = M_ID_LBSS;
#endif
}
/*
* Retain this .bss input section as this will be where global
* symbol references are added.
*/
return (S_ERROR);
/*
* If relocations exist against .*bss section, a
* section symbol must be created for the section in
* the .dynsym symbol table.
*/
else
ofl->ofl_dynshdrcnt++;
}
}
return (1);
}
/*
* Build a SHT_{INIT|FINI|PREINIT}ARRAY section (specified via
* ld -z *array=name
*/
static uintptr_t
{
return (1);
entcount = 0;
entcount++;
return (S_ERROR);
return (S_ERROR);
return (S_ERROR);
/*
* Create relocations against this section to initialize it to the
* function addresses.
*/
/*
* Fabricate the relocation information (as if a relocation record had
* been input - see init_rel()).
*/
reld.rel_roffset = 0;
reld.rel_raddend = 0;
reld.rel_typedata = 0;
/*
* Create a minimal relocation record to satisfy process_sym_reloc()
* debugging requirements.
*/
return (S_ERROR);
}
return (1);
}
/*
* Build a comment section (-Qy option).
*/
static uintptr_t
{
return (S_ERROR);
}
/*
* Make the dynamic section. Calculate the size of any strings referenced
* within this structure, they will be added to the global string table
* (.dynstr). This routine should be called before make_dynstr().
*/
static uintptr_t
{
int unused = 0;
return (S_ERROR);
/* new_section() does not set SHF_ALLOC. Add it if needed */
if (!(flags & FLG_OF_RELOBJ))
/*
* Reserve entries for any needed dependencies.
*/
continue;
/*
* If this dependency didn't satisfy any symbol references,
* generate a debugging diagnostic (ld(1) -Dunused can be used
* to display these). If this is a standard needed dependency,
* and -z ignore is in effect, drop the dependency. Explicitly
* defined dependencies (i.e., -N dep) don't get dropped, and
* are flagged as being required to simplify update_odynamic()
* processing.
*/
if (unused++ == 0)
continue;
}
/*
* If this object has an accompanying shared object definition
* determine if an alternative shared object name has been
* specified.
*/
/*
* If this object is a lazyload reserve a DT_POSFLAG1 entry.
*/
cnt++;
return (S_ERROR);
cnt++;
/*
* If the needed entry contains the $ORIGIN token make sure
* the associated DT_1_FLAGS entry is created.
*/
}
}
if (unused)
/*
*/
if (ofl->ofl_dtsfltrs) {
/* LINTED */
Dfltr_desc * dftp;
cnt++;
}
/*
* Reserve entries for any _init() and _fini() section addresses.
*/
cnt++;
}
cnt++;
}
/*
* Reserve entries for any soname, filter name (shared libs only),
* run-path pointers, cache names and audit requirements..
*/
if (ofl->ofl_soname) {
cnt++;
return (S_ERROR);
}
if (ofl->ofl_filtees) {
cnt++;
return (S_ERROR);
/*
* If the filtees entry contains the $ORIGIN token make sure
* the associated DT_1_FLAGS entry is created.
*/
}
}
return (S_ERROR);
/*
* If the rpath entry contains the $ORIGIN token make sure
* the associated DT_1_FLAGS entry is created.
*/
}
}
if (ofl->ofl_config) {
cnt++;
return (S_ERROR);
/*
* If the config entry contains the $ORIGIN token make sure
* the associated DT_1_FLAGS entry is created.
*/
}
}
if (ofl->ofl_depaudit) {
cnt++;
return (S_ERROR);
}
cnt++;
return (S_ERROR);
}
/*
* The following DT_* entries do not apply to relocatable objects
*/
/*
* Reserve entries for the HASH, STRTAB, STRSZ, SYMTAB, SYMENT,
* and CHECKSUM.
*/
cnt += 6;
/*
* If we are including local functions at the head of
* the dynsym, then also reserve entries for DT_SUNW_SYMTAB
* and DT_SUNW_SYMSZ.
*/
if (OFL_ALLOW_LDYNSYM(ofl))
cnt += 2;
if ((ofl->ofl_dynsymsortcnt > 0) ||
(ofl->ofl_dyntlssortcnt > 0))
cnt++; /* DT_SUNW_SORTENT */
if (ofl->ofl_dynsymsortcnt > 0)
if (ofl->ofl_dyntlssortcnt > 0)
cnt++;
cnt++;
cnt += 2;
cnt += 2;
/*
* If we have plt's reserve a PLT, PLTSZ, PLTREL and JMPREL.
*/
if (ofl->ofl_pltcnt)
cnt += 3;
/*
* If pltpadding is needed (Sparcv9)
*/
if (ofl->ofl_pltpad)
/*
* If we have any relocations reserve a REL, RELSZ and
* RELENT entry.
*/
if (ofl->ofl_relocsz)
cnt += 3;
/*
* If a syminfo section is required create SYMINFO, SYMINSZ,
* and SYMINENT entries.
*/
cnt += 3;
/*
* If there are any partially initialized sections allocate
* MOVEENT, MOVESZ and MOVETAB.
*/
if (ofl->ofl_osmove)
cnt += 3;
/*
* Allocate one DT_REGISTER entry for every register symbol.
*/
/*
* Reserve a entry for each '-zrtldinfo=...' specified
* on the command line.
*/
cnt++;
/*
* These two entries should only be placed in a segment
* which is writable. If it's a read-only segment
* (due to mapfile magic, e.g. libdl.so.1) then don't allocate
* these entries.
*/
cnt++; /* FEATURE_1 */
if (ofl->ofl_osinterp)
cnt++; /* DEBUG */
}
/*
*/
cnt++; /* SUNW_CAP */
}
if (flags & FLG_OF_SYMBOLIC)
cnt++; /* SYMBOLIC */
/*
* Account for Architecture dependent .dynamic entries, and defaults.
*/
/* and DT_NULL */
/*
* Determine the size of the section from the number of entries.
*/
}
/*
* Build the GOT section and its associated relocation entries.
*/
{
return (S_ERROR);
return (S_ERROR);
return (1);
}
/*
* Build an interpreter section.
*/
static uintptr_t
{
/*
* If -z nointerp is in effect, don't create an interpreter section.
*/
return (1);
/*
* We always build an .interp section for dynamic executables. However
* if the user has specifically specified an interpreter we'll build
* this section for any output (presumably the user knows what they are
* doing. refer ABI section 5-4, and ld.1 man page use of -I).
*/
return (1);
/*
* In the case of a dynamic executable supply a default interpreter
* if a specific interpreter has not been specified.
*/
if (iname == 0) {
else
}
return (S_ERROR);
}
/*
*/
static uintptr_t
{
/*
* Determine how many entries are required.
*/
if (ofl->ofl_hwcap_1)
size++;
if (ofl->ofl_sfcap_1)
size++;
if (size == 0)
return (1);
size++; /* Add CA_SUNW_NULL */
return (S_ERROR);
return (S_ERROR);
if (ofl->ofl_hwcap_1) {
cap++;
}
if (ofl->ofl_sfcap_1) {
cap++;
}
/*
* If we're not creating a relocatable object, save the output section
* to trigger the creation of an associated program header.
*/
}
/*
* Build the PLT section and its associated relocation entries.
*/
static uintptr_t
{
#if defined(sparc)
/*
* Account for the NOP at the end of the plt.
*/
#endif
return (S_ERROR);
return (S_ERROR);
return (1);
}
/*
* Make the hash table. Only built for dynamic executables and shared
* libraries, and provides hashed lookup into the global symbol table
* (.dynsym) for the run-time linker to resolve symbol lookups.
*/
static uintptr_t
{
/*
* Allocate section header structures. We set entcnt to 0
* because it's going to change after we place this section.
*/
return (S_ERROR);
/*
* Place the section first since it will affect the local symbol
* count.
*/
return (S_ERROR);
/*
* Calculate the number of output hash buckets.
*/
/*
* The size of the hash table is determined by
*
* i. the initial nbucket and nchain entries (2)
* ii. the number of buckets (calculated above)
* iii. the number of chains (this is based on the number of
* symbols in the .dynsym array + NULL symbol).
*/
/*
* Finalize the section header and data buffer initialization.
*/
return (S_ERROR);
return (1);
}
/*
* Generate the standard symbol table. Contains all locals and globals,
* and resides in a non-allocatable section (ie. it can be stripped).
*/
static uintptr_t
{
/*
* Create the section headers. Note that we supply an ent_cnt
* of 0. We won't know the count until the section has been placed.
*/
return (S_ERROR);
/*
* Place the section first since it will affect the local symbol
* count.
*/
return (S_ERROR);
/*
* At this point we've created all but the 'shstrtab' section.
* Determine if we have to use 'Extended Sections'. If so - then
* also create a SHT_SYMTAB_SHNDX section.
*/
return (S_ERROR);
return (S_ERROR);
}
/*
* Calculated number of symbols, which need to be augmented by
* the null first entry, the FILE symbol, and the .shstrtab entry.
*/
/*
* Finalize the section header and data buffer initialization.
*/
/*
* If we created a SHT_SYMTAB_SHNDX - then set it's sizes too.
*/
if (xisec) {
}
return (1);
}
/*
* Build a dynamic symbol table. These tables reside in the text
* segment of a dynamic executable or shared library.
*
* .SUNW_ldynsym contains local function symbols
* .dynsym contains only globals symbols
*
* The two tables are created adjacent to each other, with .SUNW_ldynsym
* coming first.
*/
static uintptr_t
{
int allow_ldynsym;
/*
* Unless explicitly disabled, always produce a .SUNW_ldynsym section
* when it is allowed by the file type, even if the resulting
* table only ends up with a single STT_FILE in it. There are
* two reasons: (1) It causes the generation of the DT_SUNW_SYMTAB
* entry in the .dynamic section, which is something we would
* like to encourage, and (2) Without it, we cannot generate
* the associated .SUNW_dyn[sym|tls]sort sections, which are of
* value to DTrace.
*
* In practice, it is extremely rare for an object not to have
* local symbols for .SUNW_ldynsym, so 99% of the time, we'd be
* doing it anyway.
*/
/*
* Create the section headers. Note that we supply an ent_cnt
* of 0. We won't know the count until the section has been placed.
*/
return (S_ERROR);
return (S_ERROR);
/*
* Place the section(s) first since it will affect the local symbol
* count.
*/
if (allow_ldynsym &&
return (S_ERROR);
return (S_ERROR);
/*
* One extra section header entry for the 'null' entry.
*/
/*
* Finalize the section header and data buffer initialization.
*/
/*
* An ldynsym contains local function symbols. It is not
* used for linking, but if present, serves to allow better
* stack traces to be generated in contexts where the symtab
* is not available. (dladdr(), or stripped executable/library files).
*/
if (allow_ldynsym) {
}
return (1);
}
/*
* index sections for the .SUNW_ldynsym/.dynsym pair that present data
* and function symbols sorted by address.
*/
static uintptr_t
{
/* Only do it if the .SUNW_ldynsym section is present */
if (!OFL_ALLOW_LDYNSYM(ofl))
return (1);
/* .SUNW_dynsymsort */
if (ofl->ofl_dynsymsortcnt > 0) {
return (S_ERROR);
return (S_ERROR);
}
/* .SUNW_dyntlssort */
if (ofl->ofl_dyntlssortcnt > 0) {
return (S_ERROR);
return (S_ERROR);
}
return (1);
}
/*
* Helper routine for make_dynsym_shndx. Builds a
* a SHT_SYMTAB_SHNDX for .dynsym or .SUNW_ldynsym, without knowing
* which one it is.
*/
static uintptr_t
{
return (S_ERROR);
return (S_ERROR);
return (1);
}
/*
* Build a SHT_SYMTAB_SHNDX for the .dynsym, and .SUNW_ldynsym
*/
static uintptr_t
{
/*
* If there is a .SUNW_ldynsym, generate a section for its extended
* index section as well.
*/
if (OFL_ALLOW_LDYNSYM(ofl)) {
return (S_ERROR);
}
/* The Generate a section for the dynsym */
return (S_ERROR);
return (1);
}
/*
* Build a string table for the section headers.
*/
static uintptr_t
{
return (S_ERROR);
/*
* Place the section first, as it may effect the number of section
* headers to account for.
*/
return (S_ERROR);
return (1);
}
/*
* Build a string section for the standard symbol table.
*/
static uintptr_t
{
/*
* This string table consists of all the global and local symbols.
* Account for null bytes at end of the file name and the beginning
* of section.
*/
return (S_ERROR);
return (S_ERROR);
/* Set the size of the data area */
}
/*
* Build a string table for the dynamic symbol table.
*/
static uintptr_t
{
/*
* If producing a .SUNW_ldynsym, account for the initial STT_FILE
* symbol that precedes the scope reduced global symbols.
*/
if (OFL_ALLOW_LDYNSYM(ofl)) {
return (S_ERROR);
ofl->ofl_dynscopecnt++;
}
/*
* Account for any local, named register symbols. These locals are
* required for reference from DT_REGISTER .dynamic entries.
*/
if (ofl->ofl_regsyms) {
int ndx;
continue;
continue;
continue;
return (S_ERROR);
}
}
/*
*/
if (ofl->ofl_dtsfltrs) {
Dfltr_desc * dftp;
return (S_ERROR);
}
return (S_ERROR);
/* Make it allocable if necessary */
/* Set the size of the data area */
}
/*
* Generate an output relocation section which will contain the relocation
* information to be applied to the `osp' section.
*
* If (osp == NULL) then we are creating the coalesced relocation section
*/
static uintptr_t
{
char *sectname;
const char *rel_prefix;
/* LINTED */
if (M_REL_SHT_TYPE == SHT_REL) {
/* REL */
} else {
/* RELA */
}
if (osp) {
return (S_ERROR);
} else {
sectname = (char *)rel_prefix;
}
/*
* Keep track of total size of 'output relocations' (to be stored
* in .dynamic)
*/
/* LINTED */
== S_ERROR)
return (S_ERROR);
if (osp) {
/*
* The sh_info field of the SHT_REL* sections points to the
* section the relocations are to be applied to.
*/
}
/*
* Associate this relocation section to the section its going to
* relocate.
*/
return (S_ERROR);
if (osp) {
/*
* We associate the input relocation sections - with
* the newly created output relocation section.
*
* This is used primarily so that we can update
* SHT_GROUP[sect_no] entries to point to the
* created output relocation sections.
*/
/*
* If the input relocation section had the SHF_GROUP
* flag set - propagate it to the output relocation
* section.
*/
break;
}
}
} else
/*
* If this is the first relocation section we've encountered save it
* so that the .dynamic entry can be initialized accordingly.
*/
return (1);
}
/*
* Generate version needed section.
*/
static uintptr_t
{
/*
* verneed sections do not have a constant element size, so the
* value of ent_cnt specified here (0) is meaningless.
*/
return (S_ERROR);
/* During version processing we calculated the total size. */
}
/*
* Generate a version definition section.
*
* o the SHT_SUNW_verdef section defines the versions that exist within this
* image.
*/
static uintptr_t
{
/*
* Reserve a string table entry for the base version dependency (other
* dependencies have symbol representations, which will already be
* accounted for during symbol processing).
*/
return (S_ERROR);
} else {
return (S_ERROR);
}
/*
* verdef sections do not have a constant element size, so the
* value of ent_cnt specified here (0) is meaningless.
*/
return (S_ERROR);
/* During version processing we calculated the total size. */
}
/*
* Common function used to build both the SHT_SUNW_versym
* section and the SHT_SUNW_syminfo section. Each of these sections
* provides additional symbol information.
*/
static Os_desc *
{
/*
* We don't know the size of this section yet, so set it to 0.
* It gets filled in after the dynsym is sized.
*/
}
/*
* Build a .sunwbss section for allocation of tentative definitions.
*/
{
/*
* Allocate header structs. We will set the name ourselves below,
* and there is no entcnt for a BSS. So, the shname and entcnt
* arguments are 0.
*/
return (S_ERROR);
/*
* Retain this .sunwbss input section as this will be where global
* symbol references are added.
*/
return (S_ERROR);
return (1);
}
/*
* This routine is called when -z nopartial is in effect.
*/
{
return (S_ERROR);
if (align != 0) {
}
return (S_ERROR);
/*
* Retain this .sunwdata1 input section as this will
* be where global
* symbol references are added.
*/
return (S_ERROR);
ofl->ofl_dynshdrcnt++;
}
return (1);
}
/*
* Make .sunwmove section
*/
{
int cnt = 1;
return (S_ERROR);
return (S_ERROR);
/*
* Copy move entries
*/
continue;
continue;
cnt++;
}
}
return (S_ERROR);
return (1);
}
/*
* The following sections are built after all input file processing and symbol
* validation has been carried out. The order is important (because the
* addition of a section adds a new symbol there is a chicken and egg problem
* of maintaining the appropriate counts). By maintaining a known order the
* individual routines can compensate for later, known, additions.
*/
{
/*
* Generate any special sections.
*/
if (flags & FLG_OF_ADDVERS)
return (S_ERROR);
return (S_ERROR);
return (S_ERROR);
return (S_ERROR);
return (S_ERROR);
return (S_ERROR);
/*
* Make the .plt section. This occurs after any other relocation
* sections are generated (see reloc_init()) to ensure that the
* associated relocation section is after all the other relocation
* sections.
*/
return (S_ERROR);
/*
* Determine whether any sections or files are not referenced. Under
* -Dunused a diagnostic for any unused components is generated, under
* -zignore the component is removed from the final output.
*/
return (S_ERROR);
}
/*
* Add any necessary versioning information.
*/
return (S_ERROR);
}
return (S_ERROR);
return (S_ERROR);
}
/*
* Create a syminfo section if necessary.
*/
return (S_ERROR);
}
/*
* If -zcombreloc is enabled then all relocations (except for
* the PLT's) are coalesced into a single relocation section.
*/
if (ofl->ofl_reloccnt) {
return (S_ERROR);
}
} else {
/*
* Create the required output relocation sections. Note, new
* sections may be added to the section list that is being
* traversed. These insertions can move the elements of the
* Alist such that a section descriptor is re-read. Recursion
* is prevented by maintaining a previous section pointer and
* insuring that this pointer isn't re-examined.
*/
return (S_ERROR);
}
}
}
/*
* If we're not building a combined relocation section, then
* build a .rel[a] section as required.
*/
if (ofl->ofl_relocrelsz) {
return (S_ERROR);
}
}
/*
* The PLT relocations are always in their own section, and we try to
* keep them at the end of the PLT table. We do this to keep the hot
* "data" PLT's at the head of the table nearer the .dynsym & .hash.
*/
return (S_ERROR);
}
/*
* Finally build the symbol and section header sections.
*/
if (flags & FLG_OF_DYNAMIC) {
return (S_ERROR);
return (S_ERROR);
/*
* There is no use for .hash and .dynsym sections in a
* relocatable object.
*/
if (!(flags & FLG_OF_RELOBJ)) {
return (S_ERROR);
return (S_ERROR);
return (S_ERROR);
#endif
return (S_ERROR);
}
}
/*
* Do we need to make a SHT_SYMTAB_SHNDX section
* for the dynsym. If so - do it now.
*/
if (ofl->ofl_osdynsym &&
return (S_ERROR);
}
return (S_ERROR);
return (S_ERROR);
} else {
/*
* Do we need to make a SHT_SYMTAB_SHNDX section
* for the dynsym. If so - do it now.
*/
if (ofl->ofl_osdynsym &&
return (S_ERROR);
}
}
return (S_ERROR);
/*
* Now that we've created all of our sections adjust the size
* of SHT_SUNW_versym & SHT_SUNW_syminfo which are dependent on
* the symbol table sizes.
*/
} else {
}
if (ofl->ofl_osversym) {
}
if (ofl->ofl_ossyminfo) {
}
}
return (1);
}
/*
* Build an additional data section - used to back OBJT symbol definitions
* added with a mapfile.
*/
Is_desc *
{
return (isec);
}
/*
* Define a set of templates for generating "void (*)(void)" function
* definitions.
*/
#if defined(__lint)
static const uchar_t ret_template[] = { 0 };
#else /* __lint */
#if defined(_ELF64)
#define ret_template ret64_template
#else
#define ret_template ret32_template
#endif
static const uchar_t ret32_template[] = {
/* 0x00 */ 0xc3 /* ret */
};
static const uchar_t ret64_template[] = {
/* 0x00 */ 0x55, /* pushq %rbp */
/* 0x01 */ 0x48, 0x8b, 0xec, /* movq %rsp,%rbp */
/* 0x04 */ 0x48, 0x8b, 0xe5, /* movq %rbp,%rsp */
/* 0x07 */ 0x5d, /* popq %rbp */
/* 0x08 */ 0xc3 /* ret */
};
#endif /* __lint */
static const uchar_t ret_template[] = {
/* 0x00 */ 0x81, 0xc3, 0xe0, 0x08, /* retl */
/* 0x04 */ 0x01, 0x00, 0x00, 0x00 /* nop */
};
#else
#endif
/*
* Build an additional text section - used to back FUNC symbol definitions
* added with a mapfile.
*/
Is_desc *
{
/*
* Insure the size is sufficient to contain the minimum return
* instruction.
*/
if (size < sizeof (ret_template))
size = sizeof (ret_template);
/* Fill the buffer with the appropriate return instruction. */
return (isec);
}