1d29b2c44Sab /* 2d29b2c44Sab * CDDL HEADER START 3d29b2c44Sab * 4d29b2c44Sab * The contents of this file are subject to the terms of the 5d29b2c44Sab * Common Development and Distribution License (the "License"). 6d29b2c44Sab * You may not use this file except in compliance with the License. 7d29b2c44Sab * 8d29b2c44Sab * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9d29b2c44Sab * or http://www.opensolaris.org/os/licensing. 10d29b2c44Sab * See the License for the specific language governing permissions 11d29b2c44Sab * and limitations under the License. 12d29b2c44Sab * 13d29b2c44Sab * When distributing Covered Code, include this CDDL HEADER in each 14d29b2c44Sab * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15d29b2c44Sab * If applicable, add the following below this CDDL HEADER, with the 16d29b2c44Sab * fields enclosed by brackets "[]" replaced with your own identifying 17d29b2c44Sab * information: Portions Copyright [yyyy] [name of copyright owner] 18d29b2c44Sab * 19d29b2c44Sab * CDDL HEADER END 20d29b2c44Sab */ 21d29b2c44Sab 22d29b2c44Sab /* 23*ba2be530Sab * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24d29b2c44Sab * Use is subject to license terms. 25d29b2c44Sab */ 26d29b2c44Sab #pragma ident "%Z%%M% %I% %E% SMI" 27d29b2c44Sab 28d29b2c44Sab /* 29d29b2c44Sab * ELFCLASS specific code for elfedit, built once for each class 30d29b2c44Sab */ 31d29b2c44Sab #include <stdlib.h> 32d29b2c44Sab #include <stdio.h> 33d29b2c44Sab #include <unistd.h> 34*ba2be530Sab #include <_machelf.h> 35d29b2c44Sab #include <libelf.h> 36d29b2c44Sab #include <strings.h> 37d29b2c44Sab #include <sgs.h> 38d29b2c44Sab #include "msg.h" 39d29b2c44Sab #include "_elfedit.h" 40d29b2c44Sab 41d29b2c44Sab 42d29b2c44Sab 43d29b2c44Sab /* 44d29b2c44Sab * Look up the elfedit_symtab_t that corresponds to the symbol table 45d29b2c44Sab * referenced by the sh_link field of the given auxiliary section. 46d29b2c44Sab * 47d29b2c44Sab * entry: 48d29b2c44Sab * obj_state - Partially constructed object state from 49d29b2c44Sab * elfedit_init_obj_state(). 50d29b2c44Sab * auxsec - Section that is associated with the symbol table section 51d29b2c44Sab * 52d29b2c44Sab * exit: 53d29b2c44Sab * Returns the pointer to the elfedit_symtab_t entry that is 54d29b2c44Sab * referenced by the auxiliary section. If not found, 55d29b2c44Sab * outputs a debug message, and returns NULL. 56d29b2c44Sab */ 57d29b2c44Sab static elfedit_symtab_t * 58d29b2c44Sab get_symtab(elfedit_obj_state_t *obj_state, elfedit_section_t *auxsec) 59d29b2c44Sab { 60d29b2c44Sab elfedit_symtab_t *symtab = obj_state->os_symtab; 61d29b2c44Sab Word sh_link = auxsec->sec_shdr->sh_link; 62d29b2c44Sab Word i; 63d29b2c44Sab 64d29b2c44Sab for (i = 0; i < obj_state->os_symtabnum; i++, symtab++) 65d29b2c44Sab if (symtab->symt_shndx == sh_link) 66d29b2c44Sab return (symtab); 67d29b2c44Sab 68d29b2c44Sab /* 69d29b2c44Sab * If we don't return above, it doesn't reference a valid 70d29b2c44Sab * symbol table. Issue warning. 71d29b2c44Sab */ 72d29b2c44Sab elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_AUX_LINK), 73d29b2c44Sab EC_WORD(auxsec->sec_shndx), auxsec->sec_name, 74d29b2c44Sab EC_WORD(sh_link)); 75d29b2c44Sab 76d29b2c44Sab return (NULL); 77d29b2c44Sab } 78d29b2c44Sab 79d29b2c44Sab 80d29b2c44Sab /* 81d29b2c44Sab * Fill in state.elf.obj_state with a a dynamically allocated 82d29b2c44Sab * elfedit_obj_state_t struct of the appropriate ELFCLASS. 83d29b2c44Sab * This pre-chewed form is fed to each command, reducing the amount 84d29b2c44Sab * of ELF boilerplate code each command needs to contain. 85d29b2c44Sab * 86d29b2c44Sab * entry: 87d29b2c44Sab * file - Name of file to process 88d29b2c44Sab * fd - Descriptor of open file which has been successfully 89d29b2c44Sab * processed by elf_begin(). 90d29b2c44Sab * elf - Elf handle returned by elf_begin 91d29b2c44Sab * 92d29b2c44Sab * exit: 93d29b2c44Sab * An elfedit_obj_state_t struct of the appropriate ELFCLASS has 94d29b2c44Sab * been dynamically allocated, and state.elf.obj_state references it. 95d29b2c44Sab * On failure, this routine does not return to the caller. 96d29b2c44Sab * 97d29b2c44Sab * note: The resulting elfedit_obj_state_t is allocated from a single 98d29b2c44Sab * piece of memory, such that a single call to free() suffices 99d29b2c44Sab * to release it as well as any memory it references. 100d29b2c44Sab */ 101d29b2c44Sab #ifdef _ELF64 102d29b2c44Sab void 103d29b2c44Sab elfedit64_init_obj_state(const char *file, int fd, Elf *elf) 104d29b2c44Sab #else 105d29b2c44Sab void 106d29b2c44Sab elfedit32_init_obj_state(const char *file, int fd, Elf *elf) 107d29b2c44Sab #endif 108d29b2c44Sab { 109d29b2c44Sab #define INITIAL_SYMTABNDX_ALLOC 5 110d29b2c44Sab 111d29b2c44Sab /* 112d29b2c44Sab * This macro is used to call functions from libelf, all of which 113d29b2c44Sab * return NULL for failure and something else for success. On error, 114d29b2c44Sab * libelf_fail_name is set and execution jumps to the libelf_failure 115d29b2c44Sab * label for handling. Otherwise, the results of the call are ready 116d29b2c44Sab * for use by the caller. 117d29b2c44Sab */ 118d29b2c44Sab #define LIBELF(_libelf_expr, _name) \ 119d29b2c44Sab if ((_libelf_expr) == NULL) { \ 120d29b2c44Sab libelf_fail_name = _name; \ 121d29b2c44Sab goto libelf_failure; \ 122d29b2c44Sab } 123d29b2c44Sab 124d29b2c44Sab const char *libelf_fail_name; /* Used for LIBELF errors */ 125d29b2c44Sab 126d29b2c44Sab Elf_Scn *scn; 127d29b2c44Sab Elf_Data *data; 128d29b2c44Sab uint_t ndx; 129d29b2c44Sab size_t len, os_size, secarr_size; 130d29b2c44Sab char *names = 0; 131d29b2c44Sab size_t names_len; 132d29b2c44Sab elfedit_section_t *_cache; 133d29b2c44Sab elfedit_obj_state_t tstate; 134d29b2c44Sab elfedit_obj_state_t *obj_state = NULL; 135d29b2c44Sab Word *symtabndx = NULL; 136d29b2c44Sab Word symtabndx_size = 0; 137d29b2c44Sab elfedit_symtab_t *symtab; 138d29b2c44Sab 139d29b2c44Sab tstate.os_file = file; 140d29b2c44Sab tstate.os_fd = fd; 141d29b2c44Sab tstate.os_elf = elf; 142d29b2c44Sab tstate.os_dynndx = SHN_UNDEF; 143d29b2c44Sab tstate.os_symtabnum = 0; 144d29b2c44Sab 145d29b2c44Sab LIBELF(tstate.os_ehdr = elf_getehdr(tstate.os_elf), 146d29b2c44Sab MSG_ORIG(MSG_ELF_GETEHDR)) 147d29b2c44Sab 148d29b2c44Sab /* Program header array count and address */ 149d29b2c44Sab LIBELF(elf_getphnum(tstate.os_elf, &tstate.os_phnum), 150d29b2c44Sab MSG_ORIG(MSG_ELF_GETPHNUM)) 151d29b2c44Sab if (tstate.os_phnum > 0) { 152d29b2c44Sab LIBELF((tstate.os_phdr = elf_getphdr(tstate.os_elf)), 153d29b2c44Sab MSG_ORIG(MSG_ELF_GETPHDR)) 154d29b2c44Sab } else { 155d29b2c44Sab tstate.os_phdr = NULL; 156d29b2c44Sab } 157d29b2c44Sab 158d29b2c44Sab 159d29b2c44Sab LIBELF(elf_getshnum(tstate.os_elf, &tstate.os_shnum), 160d29b2c44Sab MSG_ORIG(MSG_ELF_GETSHNUM)) 161d29b2c44Sab 162d29b2c44Sab 163d29b2c44Sab /* 164d29b2c44Sab * Obtain the .shstrtab data buffer to provide the required section 165d29b2c44Sab * name strings. 166d29b2c44Sab */ 167d29b2c44Sab LIBELF(elf_getshstrndx(tstate.os_elf, &tstate.os_shstrndx), 168d29b2c44Sab MSG_ORIG(MSG_ELF_GETSHSTRNDX)) 169d29b2c44Sab LIBELF((scn = elf_getscn(tstate.os_elf, tstate.os_shstrndx)), 170d29b2c44Sab MSG_ORIG(MSG_ELF_GETSCN)) 171d29b2c44Sab LIBELF((data = elf_getdata(scn, NULL)), MSG_ORIG(MSG_ELF_GETDATA)) 172d29b2c44Sab names = data->d_buf; 173d29b2c44Sab names_len = (names == NULL) ? 0 : data->d_size; 174d29b2c44Sab 175d29b2c44Sab /* 176d29b2c44Sab * Count the number of symbol tables and capture their indexes. 177d29b2c44Sab * Find the dynamic section. 178d29b2c44Sab */ 179d29b2c44Sab for (ndx = 1, scn = NULL; scn = elf_nextscn(tstate.os_elf, scn); 180d29b2c44Sab ndx++) { 181d29b2c44Sab Shdr *shdr; 182d29b2c44Sab 183d29b2c44Sab LIBELF(shdr = elf_getshdr(scn), MSG_ORIG(MSG_ELF_GETSHDR)); 184d29b2c44Sab 185d29b2c44Sab switch (shdr->sh_type) { 186d29b2c44Sab case SHT_DYNAMIC: 187d29b2c44Sab /* Save index of dynamic section for use below */ 188d29b2c44Sab tstate.os_dynndx = ndx; 189d29b2c44Sab break; 190d29b2c44Sab 191d29b2c44Sab case SHT_SYMTAB: 192d29b2c44Sab case SHT_DYNSYM: 193d29b2c44Sab case SHT_SUNW_LDYNSYM: 194d29b2c44Sab if (symtabndx_size <= tstate.os_symtabnum) { 195d29b2c44Sab symtabndx_size = (symtabndx_size == 0) ? 196d29b2c44Sab INITIAL_SYMTABNDX_ALLOC : 197d29b2c44Sab (symtabndx_size * 2); 198d29b2c44Sab symtabndx = elfedit_realloc( 199d29b2c44Sab MSG_INTL(MSG_ALLOC_SYMTABOS), symtabndx, 200d29b2c44Sab symtabndx_size * sizeof (symtabndx[0])); 201d29b2c44Sab } 202d29b2c44Sab symtabndx[tstate.os_symtabnum++] = ndx; 203d29b2c44Sab break; 204d29b2c44Sab } 205d29b2c44Sab } 206d29b2c44Sab 207d29b2c44Sab /* 208d29b2c44Sab * Allocate space to hold the state. We allocate space for everything 209d29b2c44Sab * in one chunk to make releasing it easy: 210d29b2c44Sab * (1) elfedit_obj_state_t struct 211d29b2c44Sab * (2) The array of elfedit_section_t items referenced from 212d29b2c44Sab * the elfedit_obj_state_t struct. 213d29b2c44Sab * (3) The array of elfedit_symtab_t items referenced from 214d29b2c44Sab * the elfedit_obj_state_t struct. 215d29b2c44Sab * (4) The file name. 216d29b2c44Sab * 217d29b2c44Sab * Note that we round up the size of (1) and (2) to a double boundary 218d29b2c44Sab * to ensure proper alignment of (2) and (3). (4) can align on any 219d29b2c44Sab * boundary. 220d29b2c44Sab */ 221d29b2c44Sab os_size = S_DROUND(sizeof (tstate)); 222d29b2c44Sab secarr_size = (tstate.os_shnum * sizeof (elfedit_section_t)); 223d29b2c44Sab secarr_size = S_DROUND(secarr_size); 224d29b2c44Sab len = strlen(tstate.os_file) + 1; 225d29b2c44Sab obj_state = elfedit_malloc(MSG_INTL(MSG_ALLOC_OBJSTATE), 226d29b2c44Sab os_size + secarr_size + 227d29b2c44Sab (tstate.os_symtabnum * sizeof (elfedit_symtab_t)) + len); 228d29b2c44Sab *obj_state = tstate; 229d29b2c44Sab 230d29b2c44Sab /*LINTED E_BAD_PTR_CAST_ALIGN*/ 231d29b2c44Sab obj_state->os_secarr = (elfedit_section_t *) 232d29b2c44Sab ((char *)obj_state + os_size); 233d29b2c44Sab if (obj_state->os_symtabnum == 0) 234d29b2c44Sab obj_state->os_symtab = NULL; 235d29b2c44Sab else 236d29b2c44Sab /*LINTED E_BAD_PTR_CAST_ALIGN*/ 237d29b2c44Sab obj_state->os_symtab = (elfedit_symtab_t *) 238d29b2c44Sab ((char *)obj_state->os_secarr + secarr_size); 239d29b2c44Sab obj_state->os_file = 240d29b2c44Sab (char *)(obj_state->os_symtab + tstate.os_symtabnum); 241d29b2c44Sab (void) strncpy((char *)obj_state->os_file, tstate.os_file, len); 242d29b2c44Sab 243d29b2c44Sab /* 244d29b2c44Sab * Fill in obj_state->os_secarr with information for each section. 245d29b2c44Sab * At the same time, fill in obj_state->os_symtab with the symbol 246d29b2c44Sab * table related data. 247d29b2c44Sab */ 248d29b2c44Sab bzero(obj_state->os_secarr, sizeof (obj_state->os_secarr[0])); 249d29b2c44Sab _cache = obj_state->os_secarr; 250d29b2c44Sab LIBELF(scn = elf_getscn(tstate.os_elf, 0), 251d29b2c44Sab MSG_ORIG(MSG_ELF_GETSCN)); 252d29b2c44Sab _cache->sec_scn = scn; 253d29b2c44Sab LIBELF(_cache->sec_shdr = elf_getshdr(scn), MSG_ORIG(MSG_ELF_GETSHDR)); 254d29b2c44Sab _cache->sec_name = (_cache->sec_shdr->sh_name < names_len) ? 255d29b2c44Sab (names + _cache->sec_shdr->sh_name) : MSG_INTL(MSG_UNKNOWNSECNAM); 256d29b2c44Sab _cache++; 257d29b2c44Sab 258d29b2c44Sab if (obj_state->os_symtab != NULL) { 259d29b2c44Sab bzero(obj_state->os_symtab, 260d29b2c44Sab sizeof (obj_state->os_symtab[0]) * obj_state->os_symtabnum); 261d29b2c44Sab for (ndx = 0; ndx < obj_state->os_symtabnum; ndx++) 262d29b2c44Sab obj_state->os_symtab[ndx].symt_shndx = symtabndx[ndx]; 263d29b2c44Sab free(symtabndx); 264d29b2c44Sab } 265d29b2c44Sab 266d29b2c44Sab for (ndx = 1, scn = NULL; scn = elf_nextscn(tstate.os_elf, scn); 267d29b2c44Sab ndx++, _cache++) { 268d29b2c44Sab _cache->sec_shndx = ndx; 269d29b2c44Sab _cache->sec_scn = scn; 270d29b2c44Sab LIBELF(_cache->sec_shdr = elf_getshdr(scn), 271d29b2c44Sab MSG_ORIG(MSG_ELF_GETSHDR)) 272d29b2c44Sab _cache->sec_data = elf_getdata(scn, NULL); 273d29b2c44Sab _cache->sec_name = (_cache->sec_shdr->sh_name < names_len) ? 274d29b2c44Sab (names + _cache->sec_shdr->sh_name) : 275d29b2c44Sab MSG_INTL(MSG_UNKNOWNSECNAM); 276d29b2c44Sab 277d29b2c44Sab switch (_cache->sec_shdr->sh_type) { 278d29b2c44Sab case SHT_SYMTAB_SHNDX: 279d29b2c44Sab symtab = get_symtab(obj_state, _cache); 280d29b2c44Sab symtab->symt_xshndx = ndx; 281d29b2c44Sab break; 282d29b2c44Sab 283d29b2c44Sab case SHT_SUNW_syminfo: 284d29b2c44Sab symtab = get_symtab(obj_state, _cache); 285d29b2c44Sab symtab->symt_syminfo = ndx; 286d29b2c44Sab break; 287d29b2c44Sab 288d29b2c44Sab case SHT_SUNW_versym: 289d29b2c44Sab symtab = get_symtab(obj_state, _cache); 290d29b2c44Sab symtab->symt_versym = ndx; 291d29b2c44Sab break; 292d29b2c44Sab } 293d29b2c44Sab } 294d29b2c44Sab 295d29b2c44Sab /* 296d29b2c44Sab * Sanity check the symbol tables, and discard any auxiliary 297d29b2c44Sab * sections without enough elements. 298d29b2c44Sab */ 299d29b2c44Sab symtab = obj_state->os_symtab; 300d29b2c44Sab for (ndx = 0; ndx < obj_state->os_symtabnum; ndx++, symtab++) { 301d29b2c44Sab elfedit_section_t *symsec; 302d29b2c44Sab Word symsec_cnt, aux_cnt; 303d29b2c44Sab 304d29b2c44Sab symsec = &obj_state->os_secarr[symtab->symt_shndx]; 305d29b2c44Sab symsec_cnt = symsec->sec_shdr->sh_size / sizeof (Sym); 306d29b2c44Sab 307d29b2c44Sab /* Extended section indexes */ 308d29b2c44Sab if (symtab->symt_xshndx != SHN_UNDEF) { 309d29b2c44Sab _cache = &obj_state->os_secarr[symtab->symt_xshndx]; 310d29b2c44Sab aux_cnt = _cache->sec_shdr->sh_size / sizeof (Word); 311d29b2c44Sab if (symsec_cnt > aux_cnt) 312d29b2c44Sab elfedit_msg(ELFEDIT_MSG_DEBUG, 313d29b2c44Sab MSG_INTL(MSG_DEBUG_AUX_SIZE), 314d29b2c44Sab EC_WORD(ndx), _cache->sec_name, 315d29b2c44Sab EC_WORD(aux_cnt), 316d29b2c44Sab EC_WORD(symsec->sec_shndx), 317d29b2c44Sab symsec->sec_name, EC_WORD(aux_cnt)); 318d29b2c44Sab } 319d29b2c44Sab 320d29b2c44Sab /* Syminfo */ 321d29b2c44Sab if (symtab->symt_syminfo != SHN_UNDEF) { 322d29b2c44Sab _cache = &obj_state->os_secarr[symtab->symt_syminfo]; 323d29b2c44Sab aux_cnt = _cache->sec_shdr->sh_size / sizeof (Syminfo); 324d29b2c44Sab if (symsec_cnt > aux_cnt) 325d29b2c44Sab elfedit_msg(ELFEDIT_MSG_DEBUG, 326d29b2c44Sab MSG_INTL(MSG_DEBUG_AUX_SIZE), 327d29b2c44Sab EC_WORD(ndx), _cache->sec_name, 328d29b2c44Sab EC_WORD(aux_cnt), 329d29b2c44Sab EC_WORD(symsec->sec_shndx), 330d29b2c44Sab symsec->sec_name, EC_WORD(aux_cnt)); 331d29b2c44Sab } 332d29b2c44Sab 333d29b2c44Sab /* Versym */ 334d29b2c44Sab if (symtab->symt_versym != SHN_UNDEF) { 335d29b2c44Sab _cache = &obj_state->os_secarr[symtab->symt_versym]; 336d29b2c44Sab aux_cnt = _cache->sec_shdr->sh_size / sizeof (Versym); 337d29b2c44Sab if (symsec_cnt > aux_cnt) 338d29b2c44Sab elfedit_msg(ELFEDIT_MSG_DEBUG, 339d29b2c44Sab MSG_INTL(MSG_DEBUG_AUX_SIZE), 340d29b2c44Sab EC_WORD(ndx), _cache->sec_name, 341d29b2c44Sab EC_WORD(aux_cnt), 342d29b2c44Sab EC_WORD(symsec->sec_shndx), 343d29b2c44Sab symsec->sec_name, EC_WORD(aux_cnt)); 344d29b2c44Sab } 345d29b2c44Sab } 346d29b2c44Sab 347d29b2c44Sab /* 348d29b2c44Sab * If this object has a dynsym section with a FLAGS_1 field, 349d29b2c44Sab * then set the DF_1_EDITED bit. elfedit allows changes that 350d29b2c44Sab * can break the resulting program, so knowing that a file was 351d29b2c44Sab * edited can be helpful when encountering a core file or other 352d29b2c44Sab * unexpected failure in the field. A single bit can't tell you 353d29b2c44Sab * what was changed, but it will alert you to the possibility that 354d29b2c44Sab * some additional questions might be in order. 355d29b2c44Sab */ 356d29b2c44Sab if (obj_state->os_dynndx != SHN_UNDEF) { 357d29b2c44Sab Word i; 358d29b2c44Sab Word numdyn; 359d29b2c44Sab elfedit_section_t *dynsec; 360d29b2c44Sab elfedit_dyn_elt_t flags_1_elt; 361d29b2c44Sab elfedit_dyn_elt_t null_elt; 362d29b2c44Sab Dyn *dyn; 363d29b2c44Sab 364d29b2c44Sab dynsec = &obj_state->os_secarr[obj_state->os_dynndx]; 365d29b2c44Sab dyn = (Dyn *) dynsec->sec_data->d_buf; 366d29b2c44Sab numdyn = dynsec->sec_shdr->sh_size / 367d29b2c44Sab dynsec->sec_shdr->sh_entsize; 368d29b2c44Sab elfedit_dyn_elt_init(&flags_1_elt); 369d29b2c44Sab elfedit_dyn_elt_init(&null_elt); 370d29b2c44Sab for (i = 0; i < numdyn; i++) { 371d29b2c44Sab 372d29b2c44Sab switch (dyn[i].d_tag) { 373d29b2c44Sab case DT_NULL: 374d29b2c44Sab /* 375d29b2c44Sab * Remember state of the first DT_NULL. If there 376d29b2c44Sab * are more than one (i.e. the first one is not 377d29b2c44Sab * in the final spot), and there is no flags1, 378d29b2c44Sab * then we will turn the first one into a 379d29b2c44Sab * DT_FLAGS_1. 380d29b2c44Sab */ 381d29b2c44Sab if (!null_elt.dn_seen) 382d29b2c44Sab elfedit_dyn_elt_save(&null_elt, i, 383d29b2c44Sab &dyn[i]); 384d29b2c44Sab break; 385d29b2c44Sab 386d29b2c44Sab case DT_FLAGS_1: 387d29b2c44Sab elfedit_dyn_elt_save(&flags_1_elt, i, &dyn[i]); 388d29b2c44Sab break; 389d29b2c44Sab } 390d29b2c44Sab } 391d29b2c44Sab /* If don't have a flags1 field, can we make one from a NULL? */ 392d29b2c44Sab if (!flags_1_elt.dn_seen && null_elt.dn_seen && 393d29b2c44Sab (null_elt.dn_ndx < (numdyn - 1))) { 394d29b2c44Sab elfedit_msg(ELFEDIT_MSG_DEBUG, 395d29b2c44Sab MSG_INTL(MSG_DEBUG_NULL2DYNFL1), 396d29b2c44Sab EC_WORD(obj_state->os_dynndx), 397d29b2c44Sab dynsec->sec_name, EC_WORD(null_elt.dn_ndx)); 398d29b2c44Sab flags_1_elt.dn_seen = 1; 399d29b2c44Sab flags_1_elt.dn_ndx = null_elt.dn_ndx; 400d29b2c44Sab flags_1_elt.dn_dyn.d_tag = DT_FLAGS_1; 401d29b2c44Sab flags_1_elt.dn_dyn.d_un.d_val = 0; 402d29b2c44Sab } 403d29b2c44Sab /* 404d29b2c44Sab * If there is a flags 1 field, add the edit flag if 405d29b2c44Sab * it is not present, and report it's presence otherwise. 406d29b2c44Sab */ 407d29b2c44Sab if (flags_1_elt.dn_seen) { 408d29b2c44Sab if (flags_1_elt.dn_dyn.d_un.d_val & DF_1_EDITED) { 409d29b2c44Sab elfedit_msg(ELFEDIT_MSG_DEBUG, 410d29b2c44Sab MSG_INTL(MSG_DEBUG_SEEDYNFLG), 411d29b2c44Sab EC_WORD(obj_state->os_dynndx), 412d29b2c44Sab dynsec->sec_name, 413d29b2c44Sab EC_WORD(flags_1_elt.dn_ndx)); 414d29b2c44Sab } else { 415d29b2c44Sab elfedit_msg(ELFEDIT_MSG_DEBUG, 416d29b2c44Sab MSG_INTL(MSG_DEBUG_ADDDYNFLG), 417d29b2c44Sab EC_WORD(obj_state->os_dynndx), 418d29b2c44Sab dynsec->sec_name, 419d29b2c44Sab EC_WORD(flags_1_elt.dn_ndx)); 420d29b2c44Sab flags_1_elt.dn_dyn.d_un.d_val |= DF_1_EDITED; 421d29b2c44Sab dyn[flags_1_elt.dn_ndx] = flags_1_elt.dn_dyn; 422d29b2c44Sab elfedit_modified_data(dynsec); 423d29b2c44Sab } 424d29b2c44Sab } 425d29b2c44Sab } 426d29b2c44Sab 427d29b2c44Sab #ifdef _ELF64 428d29b2c44Sab state.elf.obj_state.s64 = obj_state; 429d29b2c44Sab #else 430d29b2c44Sab state.elf.obj_state.s32 = obj_state; 431d29b2c44Sab #endif 432d29b2c44Sab return; 433d29b2c44Sab 434d29b2c44Sab libelf_failure: 435d29b2c44Sab /* 436d29b2c44Sab * Control comes here if there is an error with LIBELF. 437d29b2c44Sab * 438d29b2c44Sab * entry: 439d29b2c44Sab * libelf_fail_name - Name of failing libelf function 440d29b2c44Sab * tstate.os_file - Name of ELF file being processed 441d29b2c44Sab * tstate.os_fd - Descriptor of open ELF file 442d29b2c44Sab * 443d29b2c44Sab * exit: 444d29b2c44Sab * - dynamic memory is released if necessary 445d29b2c44Sab * - The error issued 446d29b2c44Sab */ 447d29b2c44Sab if (obj_state != NULL) 448d29b2c44Sab free(obj_state); 449d29b2c44Sab (void) close(tstate.os_fd); 450d29b2c44Sab elfedit_elferr(tstate.os_file, libelf_fail_name); 451d29b2c44Sab #undef LIBELF_FAILURE 452d29b2c44Sab #undef INITIAL_SYMTABNDX_ALLOC 453d29b2c44Sab } 454