elfedit_machelf.c revision 62b628a68db596a2d75a316dc7ffef658079231f
/*
* 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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* ELFCLASS specific code for elfedit, built once for each class
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <_machelf.h>
#include <libelf.h>
#include <strings.h>
#include <sgs.h>
#include "msg.h"
#include "_elfedit.h"
/*
* Look up the elfedit_symtab_t that corresponds to the symbol table
* referenced by the sh_link field of the given auxiliary section.
*
* entry:
* obj_state - Partially constructed object state from
* elfedit_init_obj_state().
* auxsec - Section that is associated with the symbol table section
*
* exit:
* Returns the pointer to the elfedit_symtab_t entry that is
* referenced by the auxiliary section. If not found,
* outputs a debug message, and returns NULL.
*/
static elfedit_symtab_t *
{
Word i;
return (symtab);
/*
* If we don't return above, it doesn't reference a valid
* symbol table. Issue warning.
*/
return (NULL);
}
/*
* Fill in state.elf.obj_state with a a dynamically allocated
* elfedit_obj_state_t struct of the appropriate ELFCLASS.
* This pre-chewed form is fed to each command, reducing the amount
* of ELF boilerplate code each command needs to contain.
*
* entry:
* file - Name of file to process
* fd - Descriptor of open file which has been successfully
* processed by elf_begin().
* elf - Elf handle returned by elf_begin
*
* exit:
* An elfedit_obj_state_t struct of the appropriate ELFCLASS has
* been dynamically allocated, and state.elf.obj_state references it.
* On failure, this routine does not return to the caller.
*
* note: The resulting elfedit_obj_state_t is allocated from a single
* piece of memory, such that a single call to free() suffices
* to release it as well as any memory it references.
*/
#ifdef _ELF64
void
#else
void
#endif
{
#define INITIAL_SYMTABNDX_ALLOC 5
/*
* These macros are used to call functions from libelf.
*
* LIBELF_FAIL encapsulates the common way in which we handle
* all of these errors: libelf_fail_name is set and execution
* jumps to the libelf_failure label for handling.
*
* LIBELF is used for the common case in which the function returns
* NULL for failure and something else for success.
*/
if ((_libelf_expr) == NULL) \
const char *libelf_fail_name; /* Used for LIBELF errors */
char *names = 0;
Word symtabndx_size = 0;
tstate.os_symtabnum = 0;
/* Program header array count and address */
} else {
}
/*
* Obtain the .shstrtab data buffer to provide the required section
* name strings.
*/
/*
* Count the number of symbol tables and capture their indexes.
* Find the dynamic section.
*/
ndx++) {
case SHT_DYNAMIC:
/* Save index of dynamic section for use below */
break;
case SHT_SYMTAB:
case SHT_DYNSYM:
case SHT_SUNW_LDYNSYM:
symtabndx_size = (symtabndx_size == 0) ?
(symtabndx_size * 2);
symtabndx_size * sizeof (symtabndx[0]));
}
break;
}
}
/*
* Allocate space to hold the state. We allocate space for everything
* in one chunk to make releasing it easy:
* (1) elfedit_obj_state_t struct
* (2) The array of elfedit_section_t items referenced from
* the elfedit_obj_state_t struct.
* (3) The array of elfedit_symtab_t items referenced from
* the elfedit_obj_state_t struct.
* (4) The file name.
*
* Note that we round up the size of (1) and (2) to a double boundary
* to ensure proper alignment of (2) and (3). (4) can align on any
* boundary.
*/
os_size + secarr_size +
/*LINTED E_BAD_PTR_CAST_ALIGN*/
if (obj_state->os_symtabnum == 0)
else
/*LINTED E_BAD_PTR_CAST_ALIGN*/
/*
* Fill in obj_state->os_secarr with information for each section.
* At the same time, fill in obj_state->os_symtab with the symbol
* table related data.
*/
_cache++;
}
case SHT_SYMTAB_SHNDX:
break;
case SHT_SUNW_syminfo:
break;
case SHT_SUNW_versym:
break;
}
}
/*
* Sanity check the symbol tables, and discard any auxiliary
* sections without enough elements.
*/
/* Extended section indexes */
if (symsec_cnt > aux_cnt)
}
/* Syminfo */
if (symsec_cnt > aux_cnt)
}
/* Versym */
if (symsec_cnt > aux_cnt)
}
}
/*
* If this object has a dynsym section with a FLAGS_1 field,
* then set the DF_1_EDITED bit. elfedit allows changes that
* can break the resulting program, so knowing that a file was
* edited can be helpful when encountering a core file or other
* unexpected failure in the field. A single bit can't tell you
* what was changed, but it will alert you to the possibility that
* some additional questions might be in order.
*/
Word i;
for (i = 0; i < numdyn; i++) {
case DT_NULL:
/*
* Remember state of the first DT_NULL. If there
* are more than one (i.e. the first one is not
* in the final spot), and there is no flags1,
* then we will turn the first one into a
* DT_FLAGS_1.
*/
&dyn[i]);
break;
case DT_FLAGS_1:
break;
}
}
/* If don't have a flags1 field, can we make one from a NULL? */
}
/*
* If there is a flags 1 field, add the edit flag if
* it is not present, and report it's presence otherwise.
*/
if (flags_1_elt.dn_seen) {
} else {
}
}
}
#ifdef _ELF64
#else
#endif
return;
/*
* Control comes here if there is an error with LIBELF.
*
* entry:
* libelf_fail_name - Name of failing libelf function
* tstate.os_file - Name of ELF file being processed
* tstate.os_fd - Descriptor of open ELF file
*
* exit:
* - dynamic memory is released if necessary
* - The error issued
*/
}