15088Sab196087 /*
25088Sab196087 * CDDL HEADER START
35088Sab196087 *
45088Sab196087 * The contents of this file are subject to the terms of the
55088Sab196087 * Common Development and Distribution License (the "License").
65088Sab196087 * You may not use this file except in compliance with the License.
75088Sab196087 *
85088Sab196087 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95088Sab196087 * or http://www.opensolaris.org/os/licensing.
105088Sab196087 * See the License for the specific language governing permissions
115088Sab196087 * and limitations under the License.
125088Sab196087 *
135088Sab196087 * When distributing Covered Code, include this CDDL HEADER in each
145088Sab196087 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155088Sab196087 * If applicable, add the following below this CDDL HEADER, with the
165088Sab196087 * fields enclosed by brackets "[]" replaced with your own identifying
175088Sab196087 * information: Portions Copyright [yyyy] [name of copyright owner]
185088Sab196087 *
195088Sab196087 * CDDL HEADER END
205088Sab196087 */
215088Sab196087
225088Sab196087 /*
23*9900SAli.Bahrami@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
245088Sab196087 * Use is subject to license terms.
255088Sab196087 */
265088Sab196087
275088Sab196087 /*
285088Sab196087 * ELFCLASS specific code for elfedit, built once for each class
295088Sab196087 */
305088Sab196087 #include <stdlib.h>
315088Sab196087 #include <stdio.h>
325088Sab196087 #include <unistd.h>
336206Sab196087 #include <_machelf.h>
345088Sab196087 #include <libelf.h>
355088Sab196087 #include <strings.h>
365088Sab196087 #include <sgs.h>
375088Sab196087 #include "msg.h"
385088Sab196087 #include "_elfedit.h"
395088Sab196087
405088Sab196087
415088Sab196087
425088Sab196087 /*
435088Sab196087 * Look up the elfedit_symtab_t that corresponds to the symbol table
445088Sab196087 * referenced by the sh_link field of the given auxiliary section.
455088Sab196087 *
465088Sab196087 * entry:
475088Sab196087 * obj_state - Partially constructed object state from
485088Sab196087 * elfedit_init_obj_state().
495088Sab196087 * auxsec - Section that is associated with the symbol table section
505088Sab196087 *
515088Sab196087 * exit:
525088Sab196087 * Returns the pointer to the elfedit_symtab_t entry that is
535088Sab196087 * referenced by the auxiliary section. If not found,
545088Sab196087 * outputs a debug message, and returns NULL.
555088Sab196087 */
565088Sab196087 static elfedit_symtab_t *
get_symtab(elfedit_obj_state_t * obj_state,elfedit_section_t * auxsec)575088Sab196087 get_symtab(elfedit_obj_state_t *obj_state, elfedit_section_t *auxsec)
585088Sab196087 {
595088Sab196087 elfedit_symtab_t *symtab = obj_state->os_symtab;
605088Sab196087 Word sh_link = auxsec->sec_shdr->sh_link;
615088Sab196087 Word i;
625088Sab196087
635088Sab196087 for (i = 0; i < obj_state->os_symtabnum; i++, symtab++)
645088Sab196087 if (symtab->symt_shndx == sh_link)
655088Sab196087 return (symtab);
665088Sab196087
675088Sab196087 /*
685088Sab196087 * If we don't return above, it doesn't reference a valid
695088Sab196087 * symbol table. Issue warning.
705088Sab196087 */
715088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_AUX_LINK),
725088Sab196087 EC_WORD(auxsec->sec_shndx), auxsec->sec_name,
735088Sab196087 EC_WORD(sh_link));
745088Sab196087
755088Sab196087 return (NULL);
765088Sab196087 }
775088Sab196087
785088Sab196087
795088Sab196087 /*
805088Sab196087 * Fill in state.elf.obj_state with a a dynamically allocated
815088Sab196087 * elfedit_obj_state_t struct of the appropriate ELFCLASS.
825088Sab196087 * This pre-chewed form is fed to each command, reducing the amount
835088Sab196087 * of ELF boilerplate code each command needs to contain.
845088Sab196087 *
855088Sab196087 * entry:
865088Sab196087 * file - Name of file to process
875088Sab196087 * fd - Descriptor of open file which has been successfully
885088Sab196087 * processed by elf_begin().
895088Sab196087 * elf - Elf handle returned by elf_begin
905088Sab196087 *
915088Sab196087 * exit:
925088Sab196087 * An elfedit_obj_state_t struct of the appropriate ELFCLASS has
935088Sab196087 * been dynamically allocated, and state.elf.obj_state references it.
945088Sab196087 * On failure, this routine does not return to the caller.
955088Sab196087 *
965088Sab196087 * note: The resulting elfedit_obj_state_t is allocated from a single
975088Sab196087 * piece of memory, such that a single call to free() suffices
985088Sab196087 * to release it as well as any memory it references.
995088Sab196087 */
1005088Sab196087 #ifdef _ELF64
1015088Sab196087 void
elfedit64_init_obj_state(const char * file,int fd,Elf * elf)1025088Sab196087 elfedit64_init_obj_state(const char *file, int fd, Elf *elf)
1035088Sab196087 #else
1045088Sab196087 void
1055088Sab196087 elfedit32_init_obj_state(const char *file, int fd, Elf *elf)
1065088Sab196087 #endif
1075088Sab196087 {
1085088Sab196087 #define INITIAL_SYMTABNDX_ALLOC 5
1095088Sab196087
1105088Sab196087 /*
111*9900SAli.Bahrami@Sun.COM * These macros are used to call functions from libelf.
112*9900SAli.Bahrami@Sun.COM *
113*9900SAli.Bahrami@Sun.COM * LIBELF_FAIL encapsulates the common way in which we handle
114*9900SAli.Bahrami@Sun.COM * all of these errors: libelf_fail_name is set and execution
115*9900SAli.Bahrami@Sun.COM * jumps to the libelf_failure label for handling.
116*9900SAli.Bahrami@Sun.COM *
117*9900SAli.Bahrami@Sun.COM * LIBELF is used for the common case in which the function returns
118*9900SAli.Bahrami@Sun.COM * NULL for failure and something else for success.
1195088Sab196087 */
120*9900SAli.Bahrami@Sun.COM #define LIBELF_FAIL(_name) { libelf_fail_name = _name; goto libelf_failure; }
1215088Sab196087 #define LIBELF(_libelf_expr, _name) \
122*9900SAli.Bahrami@Sun.COM if ((_libelf_expr) == NULL) \
123*9900SAli.Bahrami@Sun.COM LIBELF_FAIL(_name)
1245088Sab196087
1255088Sab196087 const char *libelf_fail_name; /* Used for LIBELF errors */
1265088Sab196087
1275088Sab196087 Elf_Scn *scn;
1285088Sab196087 Elf_Data *data;
1295088Sab196087 uint_t ndx;
1305088Sab196087 size_t len, os_size, secarr_size;
1315088Sab196087 char *names = 0;
1325088Sab196087 size_t names_len;
1335088Sab196087 elfedit_section_t *_cache;
1345088Sab196087 elfedit_obj_state_t tstate;
1355088Sab196087 elfedit_obj_state_t *obj_state = NULL;
1365088Sab196087 Word *symtabndx = NULL;
1375088Sab196087 Word symtabndx_size = 0;
1385088Sab196087 elfedit_symtab_t *symtab;
1395088Sab196087
1405088Sab196087 tstate.os_file = file;
1415088Sab196087 tstate.os_fd = fd;
1425088Sab196087 tstate.os_elf = elf;
1435088Sab196087 tstate.os_dynndx = SHN_UNDEF;
1445088Sab196087 tstate.os_symtabnum = 0;
1455088Sab196087
1465088Sab196087 LIBELF(tstate.os_ehdr = elf_getehdr(tstate.os_elf),
1475088Sab196087 MSG_ORIG(MSG_ELF_GETEHDR))
1485088Sab196087
1495088Sab196087 /* Program header array count and address */
150*9900SAli.Bahrami@Sun.COM if (elf_getphdrnum(tstate.os_elf, &tstate.os_phnum) == -1)
151*9900SAli.Bahrami@Sun.COM LIBELF_FAIL(MSG_ORIG(MSG_ELF_GETPHDRNUM))
1525088Sab196087 if (tstate.os_phnum > 0) {
1535088Sab196087 LIBELF((tstate.os_phdr = elf_getphdr(tstate.os_elf)),
1545088Sab196087 MSG_ORIG(MSG_ELF_GETPHDR))
1555088Sab196087 } else {
1565088Sab196087 tstate.os_phdr = NULL;
1575088Sab196087 }
1585088Sab196087
159*9900SAli.Bahrami@Sun.COM if (elf_getshdrnum(tstate.os_elf, &tstate.os_shnum) == -1)
160*9900SAli.Bahrami@Sun.COM LIBELF_FAIL(MSG_ORIG(MSG_ELF_GETSHDRNUM))
1615088Sab196087
1625088Sab196087 /*
1635088Sab196087 * Obtain the .shstrtab data buffer to provide the required section
1645088Sab196087 * name strings.
1655088Sab196087 */
166*9900SAli.Bahrami@Sun.COM if (elf_getshdrstrndx(tstate.os_elf, &tstate.os_shstrndx) == -1)
167*9900SAli.Bahrami@Sun.COM LIBELF_FAIL(MSG_ORIG(MSG_ELF_GETSHDRSTRNDX))
1685088Sab196087 LIBELF((scn = elf_getscn(tstate.os_elf, tstate.os_shstrndx)),
1695088Sab196087 MSG_ORIG(MSG_ELF_GETSCN))
1705088Sab196087 LIBELF((data = elf_getdata(scn, NULL)), MSG_ORIG(MSG_ELF_GETDATA))
1715088Sab196087 names = data->d_buf;
1725088Sab196087 names_len = (names == NULL) ? 0 : data->d_size;
1735088Sab196087
1745088Sab196087 /*
1755088Sab196087 * Count the number of symbol tables and capture their indexes.
1765088Sab196087 * Find the dynamic section.
1775088Sab196087 */
1785088Sab196087 for (ndx = 1, scn = NULL; scn = elf_nextscn(tstate.os_elf, scn);
1795088Sab196087 ndx++) {
1805088Sab196087 Shdr *shdr;
1815088Sab196087
1825088Sab196087 LIBELF(shdr = elf_getshdr(scn), MSG_ORIG(MSG_ELF_GETSHDR));
1835088Sab196087
1845088Sab196087 switch (shdr->sh_type) {
1855088Sab196087 case SHT_DYNAMIC:
1865088Sab196087 /* Save index of dynamic section for use below */
1875088Sab196087 tstate.os_dynndx = ndx;
1885088Sab196087 break;
1895088Sab196087
1905088Sab196087 case SHT_SYMTAB:
1915088Sab196087 case SHT_DYNSYM:
1925088Sab196087 case SHT_SUNW_LDYNSYM:
1935088Sab196087 if (symtabndx_size <= tstate.os_symtabnum) {
1945088Sab196087 symtabndx_size = (symtabndx_size == 0) ?
1955088Sab196087 INITIAL_SYMTABNDX_ALLOC :
1965088Sab196087 (symtabndx_size * 2);
1975088Sab196087 symtabndx = elfedit_realloc(
1985088Sab196087 MSG_INTL(MSG_ALLOC_SYMTABOS), symtabndx,
1995088Sab196087 symtabndx_size * sizeof (symtabndx[0]));
2005088Sab196087 }
2015088Sab196087 symtabndx[tstate.os_symtabnum++] = ndx;
2025088Sab196087 break;
2035088Sab196087 }
2045088Sab196087 }
2055088Sab196087
2065088Sab196087 /*
2075088Sab196087 * Allocate space to hold the state. We allocate space for everything
2085088Sab196087 * in one chunk to make releasing it easy:
2095088Sab196087 * (1) elfedit_obj_state_t struct
2105088Sab196087 * (2) The array of elfedit_section_t items referenced from
2115088Sab196087 * the elfedit_obj_state_t struct.
2125088Sab196087 * (3) The array of elfedit_symtab_t items referenced from
2135088Sab196087 * the elfedit_obj_state_t struct.
2145088Sab196087 * (4) The file name.
2155088Sab196087 *
2165088Sab196087 * Note that we round up the size of (1) and (2) to a double boundary
2175088Sab196087 * to ensure proper alignment of (2) and (3). (4) can align on any
2185088Sab196087 * boundary.
2195088Sab196087 */
2205088Sab196087 os_size = S_DROUND(sizeof (tstate));
2215088Sab196087 secarr_size = (tstate.os_shnum * sizeof (elfedit_section_t));
2225088Sab196087 secarr_size = S_DROUND(secarr_size);
2235088Sab196087 len = strlen(tstate.os_file) + 1;
2245088Sab196087 obj_state = elfedit_malloc(MSG_INTL(MSG_ALLOC_OBJSTATE),
2255088Sab196087 os_size + secarr_size +
2265088Sab196087 (tstate.os_symtabnum * sizeof (elfedit_symtab_t)) + len);
2275088Sab196087 *obj_state = tstate;
2285088Sab196087
2295088Sab196087 /*LINTED E_BAD_PTR_CAST_ALIGN*/
2305088Sab196087 obj_state->os_secarr = (elfedit_section_t *)
2315088Sab196087 ((char *)obj_state + os_size);
2325088Sab196087 if (obj_state->os_symtabnum == 0)
2335088Sab196087 obj_state->os_symtab = NULL;
2345088Sab196087 else
2355088Sab196087 /*LINTED E_BAD_PTR_CAST_ALIGN*/
2365088Sab196087 obj_state->os_symtab = (elfedit_symtab_t *)
2375088Sab196087 ((char *)obj_state->os_secarr + secarr_size);
2385088Sab196087 obj_state->os_file =
2395088Sab196087 (char *)(obj_state->os_symtab + tstate.os_symtabnum);
2405088Sab196087 (void) strncpy((char *)obj_state->os_file, tstate.os_file, len);
2415088Sab196087
2425088Sab196087 /*
2435088Sab196087 * Fill in obj_state->os_secarr with information for each section.
2445088Sab196087 * At the same time, fill in obj_state->os_symtab with the symbol
2455088Sab196087 * table related data.
2465088Sab196087 */
2475088Sab196087 bzero(obj_state->os_secarr, sizeof (obj_state->os_secarr[0]));
2485088Sab196087 _cache = obj_state->os_secarr;
2495088Sab196087 LIBELF(scn = elf_getscn(tstate.os_elf, 0),
2505088Sab196087 MSG_ORIG(MSG_ELF_GETSCN));
2515088Sab196087 _cache->sec_scn = scn;
2525088Sab196087 LIBELF(_cache->sec_shdr = elf_getshdr(scn), MSG_ORIG(MSG_ELF_GETSHDR));
2535088Sab196087 _cache->sec_name = (_cache->sec_shdr->sh_name < names_len) ?
2545088Sab196087 (names + _cache->sec_shdr->sh_name) : MSG_INTL(MSG_UNKNOWNSECNAM);
2555088Sab196087 _cache++;
2565088Sab196087
2575088Sab196087 if (obj_state->os_symtab != NULL) {
2585088Sab196087 bzero(obj_state->os_symtab,
2595088Sab196087 sizeof (obj_state->os_symtab[0]) * obj_state->os_symtabnum);
2605088Sab196087 for (ndx = 0; ndx < obj_state->os_symtabnum; ndx++)
2615088Sab196087 obj_state->os_symtab[ndx].symt_shndx = symtabndx[ndx];
2625088Sab196087 free(symtabndx);
2635088Sab196087 }
2645088Sab196087
2655088Sab196087 for (ndx = 1, scn = NULL; scn = elf_nextscn(tstate.os_elf, scn);
2665088Sab196087 ndx++, _cache++) {
2675088Sab196087 _cache->sec_shndx = ndx;
2685088Sab196087 _cache->sec_scn = scn;
2695088Sab196087 LIBELF(_cache->sec_shdr = elf_getshdr(scn),
2705088Sab196087 MSG_ORIG(MSG_ELF_GETSHDR))
2715088Sab196087 _cache->sec_data = elf_getdata(scn, NULL);
2725088Sab196087 _cache->sec_name = (_cache->sec_shdr->sh_name < names_len) ?
2735088Sab196087 (names + _cache->sec_shdr->sh_name) :
2745088Sab196087 MSG_INTL(MSG_UNKNOWNSECNAM);
2755088Sab196087
2765088Sab196087 switch (_cache->sec_shdr->sh_type) {
2775088Sab196087 case SHT_SYMTAB_SHNDX:
2785088Sab196087 symtab = get_symtab(obj_state, _cache);
2795088Sab196087 symtab->symt_xshndx = ndx;
2805088Sab196087 break;
2815088Sab196087
2825088Sab196087 case SHT_SUNW_syminfo:
2835088Sab196087 symtab = get_symtab(obj_state, _cache);
2845088Sab196087 symtab->symt_syminfo = ndx;
2855088Sab196087 break;
2865088Sab196087
2875088Sab196087 case SHT_SUNW_versym:
2885088Sab196087 symtab = get_symtab(obj_state, _cache);
2895088Sab196087 symtab->symt_versym = ndx;
2905088Sab196087 break;
2915088Sab196087 }
2925088Sab196087 }
2935088Sab196087
2945088Sab196087 /*
2955088Sab196087 * Sanity check the symbol tables, and discard any auxiliary
2965088Sab196087 * sections without enough elements.
2975088Sab196087 */
2985088Sab196087 symtab = obj_state->os_symtab;
2995088Sab196087 for (ndx = 0; ndx < obj_state->os_symtabnum; ndx++, symtab++) {
3005088Sab196087 elfedit_section_t *symsec;
3015088Sab196087 Word symsec_cnt, aux_cnt;
3025088Sab196087
3035088Sab196087 symsec = &obj_state->os_secarr[symtab->symt_shndx];
3045088Sab196087 symsec_cnt = symsec->sec_shdr->sh_size / sizeof (Sym);
3055088Sab196087
3065088Sab196087 /* Extended section indexes */
3075088Sab196087 if (symtab->symt_xshndx != SHN_UNDEF) {
3085088Sab196087 _cache = &obj_state->os_secarr[symtab->symt_xshndx];
3095088Sab196087 aux_cnt = _cache->sec_shdr->sh_size / sizeof (Word);
3105088Sab196087 if (symsec_cnt > aux_cnt)
3115088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
3125088Sab196087 MSG_INTL(MSG_DEBUG_AUX_SIZE),
3135088Sab196087 EC_WORD(ndx), _cache->sec_name,
3145088Sab196087 EC_WORD(aux_cnt),
3155088Sab196087 EC_WORD(symsec->sec_shndx),
3165088Sab196087 symsec->sec_name, EC_WORD(aux_cnt));
3175088Sab196087 }
3185088Sab196087
3195088Sab196087 /* Syminfo */
3205088Sab196087 if (symtab->symt_syminfo != SHN_UNDEF) {
3215088Sab196087 _cache = &obj_state->os_secarr[symtab->symt_syminfo];
3225088Sab196087 aux_cnt = _cache->sec_shdr->sh_size / sizeof (Syminfo);
3235088Sab196087 if (symsec_cnt > aux_cnt)
3245088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
3255088Sab196087 MSG_INTL(MSG_DEBUG_AUX_SIZE),
3265088Sab196087 EC_WORD(ndx), _cache->sec_name,
3275088Sab196087 EC_WORD(aux_cnt),
3285088Sab196087 EC_WORD(symsec->sec_shndx),
3295088Sab196087 symsec->sec_name, EC_WORD(aux_cnt));
3305088Sab196087 }
3315088Sab196087
3325088Sab196087 /* Versym */
3335088Sab196087 if (symtab->symt_versym != SHN_UNDEF) {
3345088Sab196087 _cache = &obj_state->os_secarr[symtab->symt_versym];
3355088Sab196087 aux_cnt = _cache->sec_shdr->sh_size / sizeof (Versym);
3365088Sab196087 if (symsec_cnt > aux_cnt)
3375088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
3385088Sab196087 MSG_INTL(MSG_DEBUG_AUX_SIZE),
3395088Sab196087 EC_WORD(ndx), _cache->sec_name,
3405088Sab196087 EC_WORD(aux_cnt),
3415088Sab196087 EC_WORD(symsec->sec_shndx),
3425088Sab196087 symsec->sec_name, EC_WORD(aux_cnt));
3435088Sab196087 }
3445088Sab196087 }
3455088Sab196087
3465088Sab196087 /*
3475088Sab196087 * If this object has a dynsym section with a FLAGS_1 field,
3485088Sab196087 * then set the DF_1_EDITED bit. elfedit allows changes that
3495088Sab196087 * can break the resulting program, so knowing that a file was
3505088Sab196087 * edited can be helpful when encountering a core file or other
3515088Sab196087 * unexpected failure in the field. A single bit can't tell you
3525088Sab196087 * what was changed, but it will alert you to the possibility that
3535088Sab196087 * some additional questions might be in order.
3545088Sab196087 */
3555088Sab196087 if (obj_state->os_dynndx != SHN_UNDEF) {
3565088Sab196087 Word i;
3575088Sab196087 Word numdyn;
3585088Sab196087 elfedit_section_t *dynsec;
3595088Sab196087 elfedit_dyn_elt_t flags_1_elt;
3605088Sab196087 elfedit_dyn_elt_t null_elt;
3615088Sab196087 Dyn *dyn;
3625088Sab196087
3635088Sab196087 dynsec = &obj_state->os_secarr[obj_state->os_dynndx];
3645088Sab196087 dyn = (Dyn *) dynsec->sec_data->d_buf;
3655088Sab196087 numdyn = dynsec->sec_shdr->sh_size /
3665088Sab196087 dynsec->sec_shdr->sh_entsize;
3675088Sab196087 elfedit_dyn_elt_init(&flags_1_elt);
3685088Sab196087 elfedit_dyn_elt_init(&null_elt);
3695088Sab196087 for (i = 0; i < numdyn; i++) {
3705088Sab196087
3715088Sab196087 switch (dyn[i].d_tag) {
3725088Sab196087 case DT_NULL:
3735088Sab196087 /*
3745088Sab196087 * Remember state of the first DT_NULL. If there
3755088Sab196087 * are more than one (i.e. the first one is not
3765088Sab196087 * in the final spot), and there is no flags1,
3775088Sab196087 * then we will turn the first one into a
3785088Sab196087 * DT_FLAGS_1.
3795088Sab196087 */
3805088Sab196087 if (!null_elt.dn_seen)
3815088Sab196087 elfedit_dyn_elt_save(&null_elt, i,
3825088Sab196087 &dyn[i]);
3835088Sab196087 break;
3845088Sab196087
3855088Sab196087 case DT_FLAGS_1:
3865088Sab196087 elfedit_dyn_elt_save(&flags_1_elt, i, &dyn[i]);
3875088Sab196087 break;
3885088Sab196087 }
3895088Sab196087 }
3905088Sab196087 /* If don't have a flags1 field, can we make one from a NULL? */
3915088Sab196087 if (!flags_1_elt.dn_seen && null_elt.dn_seen &&
3925088Sab196087 (null_elt.dn_ndx < (numdyn - 1))) {
3935088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
3945088Sab196087 MSG_INTL(MSG_DEBUG_NULL2DYNFL1),
3955088Sab196087 EC_WORD(obj_state->os_dynndx),
3965088Sab196087 dynsec->sec_name, EC_WORD(null_elt.dn_ndx));
3975088Sab196087 flags_1_elt.dn_seen = 1;
3985088Sab196087 flags_1_elt.dn_ndx = null_elt.dn_ndx;
3995088Sab196087 flags_1_elt.dn_dyn.d_tag = DT_FLAGS_1;
4005088Sab196087 flags_1_elt.dn_dyn.d_un.d_val = 0;
4015088Sab196087 }
4025088Sab196087 /*
4035088Sab196087 * If there is a flags 1 field, add the edit flag if
4045088Sab196087 * it is not present, and report it's presence otherwise.
4055088Sab196087 */
4065088Sab196087 if (flags_1_elt.dn_seen) {
4075088Sab196087 if (flags_1_elt.dn_dyn.d_un.d_val & DF_1_EDITED) {
4085088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
4095088Sab196087 MSG_INTL(MSG_DEBUG_SEEDYNFLG),
4105088Sab196087 EC_WORD(obj_state->os_dynndx),
4115088Sab196087 dynsec->sec_name,
4125088Sab196087 EC_WORD(flags_1_elt.dn_ndx));
4135088Sab196087 } else {
4145088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
4155088Sab196087 MSG_INTL(MSG_DEBUG_ADDDYNFLG),
4165088Sab196087 EC_WORD(obj_state->os_dynndx),
4175088Sab196087 dynsec->sec_name,
4185088Sab196087 EC_WORD(flags_1_elt.dn_ndx));
4195088Sab196087 flags_1_elt.dn_dyn.d_un.d_val |= DF_1_EDITED;
4205088Sab196087 dyn[flags_1_elt.dn_ndx] = flags_1_elt.dn_dyn;
4215088Sab196087 elfedit_modified_data(dynsec);
4225088Sab196087 }
4235088Sab196087 }
4245088Sab196087 }
4255088Sab196087
4265088Sab196087 #ifdef _ELF64
4275088Sab196087 state.elf.obj_state.s64 = obj_state;
4285088Sab196087 #else
4295088Sab196087 state.elf.obj_state.s32 = obj_state;
4305088Sab196087 #endif
4315088Sab196087 return;
4325088Sab196087
4335088Sab196087 libelf_failure:
4345088Sab196087 /*
4355088Sab196087 * Control comes here if there is an error with LIBELF.
4365088Sab196087 *
4375088Sab196087 * entry:
4385088Sab196087 * libelf_fail_name - Name of failing libelf function
4395088Sab196087 * tstate.os_file - Name of ELF file being processed
4405088Sab196087 * tstate.os_fd - Descriptor of open ELF file
4415088Sab196087 *
4425088Sab196087 * exit:
4435088Sab196087 * - dynamic memory is released if necessary
4445088Sab196087 * - The error issued
4455088Sab196087 */
4465088Sab196087 if (obj_state != NULL)
4475088Sab196087 free(obj_state);
4485088Sab196087 (void) close(tstate.os_fd);
4495088Sab196087 elfedit_elferr(tstate.os_file, libelf_fail_name);
4505088Sab196087 #undef INITIAL_SYMTABNDX_ALLOC
451*9900SAli.Bahrami@Sun.COM #undef LIBELF_FAIL
452*9900SAli.Bahrami@Sun.COM #undef LIBELF
4535088Sab196087 }
454