Mercurial > illumos > illumos-gate
changeset 5154:afdff8c5ab8e
6253589 mcs has problems handling multiple SHT_NOTE sections
6473571 strip and mcs get confused and corrupt files when passed non-ELF arguments
author | ab196087 |
---|---|
date | Mon, 01 Oct 2007 11:29:33 -0700 |
parents | 8508f39f49fe |
children | f8171ea20722 |
files | usr/src/cmd/sgs/mcs/common/file.c usr/src/cmd/sgs/mcs/common/mcs.h usr/src/cmd/sgs/mcs/common/utils.c usr/src/cmd/sgs/packages/common/SUNWonld-README |
diffstat | 4 files changed, 429 insertions(+), 454 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/sgs/mcs/common/file.c Mon Oct 01 11:00:58 2007 -0700 +++ b/usr/src/cmd/sgs/mcs/common/file.c Mon Oct 01 11:29:33 2007 -0700 @@ -33,20 +33,22 @@ #include "extern.h" #include "gelf.h" -static int Sect_exists = 0; -static int notesegndx = -1; -static int notesctndx = -1; -static Seg_Table *b_e_seg_table; +/* + * Type used to pass state information for the current + * file between routines. + */ +typedef struct { + int Sect_exists; + int notesegndx; + int notesctndx; + Seg_Table *b_e_seg_table; + section_info_table *sec_table; + int64_t *off_table; /* maintains section's offset; set to */ + /* retain old offset, else 0 */ + int64_t *nobits_table; /* maintains NOBITS sections */ + char *new_sec_string; +} file_state_t; -static section_info_table *sec_table; -static int64_t *off_table; /* array maintains section's offset; */ - /* set to retain old offset, else 0 */ -static int64_t *nobits_table; /* array maintains NOBITS sections */ - -static char *new_sec_string = NULL; - -#define MMAP_USED 1 -#define MMAP_UNUSED 2 /* * Function prototypes. @@ -56,13 +58,16 @@ copy_non_elf_to_temp_ar(int, Elf *, int, Elf_Arhdr *, char *, Cmd_Info *); static void copy_elf_file_to_temp_ar_file(int, Elf_Arhdr *, char *); static int process_file(Elf *, char *, Cmd_Info *); -static void initialize(int shnum, Cmd_Info *); -static int build_segment_table(Elf*, GElf_Ehdr *); -static int traverse_file(Elf *, GElf_Ehdr *, char *, Cmd_Info *); -static uint64_t location(int64_t, int, Elf *); -static uint64_t scn_location(Elf_Scn *, Elf *); -static int build_file(Elf *, GElf_Ehdr *, Cmd_Info *); -static void post_process(Cmd_Info *); +static void initialize(int shnum, Cmd_Info *, file_state_t *); +static int build_segment_table(Elf*, GElf_Ehdr *, file_state_t *); +static int traverse_file(Elf *, GElf_Ehdr *, char *, Cmd_Info *, + file_state_t *); +static uint64_t location(int64_t, int, Elf *, file_state_t *); +static uint64_t scn_location(Elf_Scn *, Elf *, file_state_t *); +static int build_file(Elf *, GElf_Ehdr *, Cmd_Info *, file_state_t *); +static void post_process(Cmd_Info *, file_state_t *); + + int each_file(char *cur_file, Cmd_Info *cmd_info) @@ -85,8 +90,8 @@ oflag = O_RDONLY; if ((fd = open(cur_file, oflag)) == -1) { - error_message(OPEN_ERROR, - SYSTEM_ERROR, strerror(errno), prog, cur_file); + error_message(OPEN_ERROR, SYSTEM_ERROR, strerror(errno), + prog, cur_file); return (FAILURE); } @@ -99,8 +104,7 @@ */ cmd = ELF_C_READ; if ((arf = elf_begin(fd, cmd, (Elf *)0)) == 0) { - error_message(LIBELF_ERROR, - LIBelf_ERROR, elf_errmsg(-1), prog); + error_message(LIBELF_ERROR, LIBelf_ERROR, elf_errmsg(-1), prog); (void) elf_end(arf); (void) close(fd); /* done processing this file */ return (FAILURE); @@ -114,8 +118,8 @@ O_WRONLY | O_APPEND | O_CREAT, (mode_t)0666)) == NULL) { error_message(OPEN_TEMP_ERROR, - SYSTEM_ERROR, strerror(errno), - prog, artmpfile); + SYSTEM_ERROR, strerror(errno), + prog, artmpfile); (void) elf_end(arf); (void) close(fd); exit(FAILURE); @@ -123,8 +127,8 @@ /* write magic string to artmpfile */ if ((write(fdartmp, ARMAG, SARMAG)) != SARMAG) { error_message(WRITE_ERROR, - SYSTEM_ERROR, strerror(errno), - prog, artmpfile, cur_file); + SYSTEM_ERROR, strerror(errno), + prog, artmpfile, cur_file); mcs_exit(FAILURE); } } @@ -146,9 +150,9 @@ size_t len; if ((mem_header = elf_getarhdr(elf)) == NULL) { - error_message(GETARHDR_ERROR, - LIBelf_ERROR, elf_errmsg(-1), - prog, cur_file, elf_getbase(elf)); + error_message(GETARHDR_ERROR, LIBelf_ERROR, + elf_errmsg(-1), prog, cur_file, + elf_getbase(elf)); (void) elf_end(elf); (void) elf_end(arf); (void) close(fd); @@ -164,13 +168,12 @@ if ((cur_filenm = malloc(len)) == NULL) { error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, - prog); + PLAIN_ERROR, (char *)0, prog); mcs_exit(FAILURE); } (void) snprintf(cur_filenm, len, "%s[%s]", - cur_file, mem_header->ar_name); + cur_file, mem_header->ar_name); } if (elf_kind(elf) == ELF_K_ELF) { @@ -182,35 +185,34 @@ (void) close(fd); return (FAILURE); } else { - copy_non_elf_to_temp_ar( - fd, elf, fdartmp, mem_header, - cur_file, cmd_info); + copy_non_elf_to_temp_ar(fd, elf, + fdartmp, mem_header, + cur_file, cmd_info); error++; } } else if (ar_file && CHK_OPT(cmd_info, MIGHT_CHG)) { if (code == DONT_BUILD) - copy_non_elf_to_temp_ar( - fd, elf, fdartmp, mem_header, - cur_file, cmd_info); + copy_non_elf_to_temp_ar(fd, elf, + fdartmp, mem_header, + cur_file, cmd_info); else copy_elf_file_to_temp_ar_file( - fdartmp, mem_header, cur_file); + fdartmp, mem_header, cur_file); } } else { /* * decide what to do with non-ELF file */ if (!ar_file) { - error_message(FILE_TYPE_ERROR, - PLAIN_ERROR, (char *)0, - prog, cur_filenm); + error_message(FILE_TYPE_ERROR, PLAIN_ERROR, + (char *)0, prog, cur_filenm); (void) close(fd); return (FAILURE); } else { if (CHK_OPT(cmd_info, MIGHT_CHG)) - copy_non_elf_to_temp_ar( - fd, elf, fdartmp, mem_header, - cur_file, cmd_info); + copy_non_elf_to_temp_ar(fd, elf, + fdartmp, mem_header, + cur_file, cmd_info); } } cmd = elf_next(elf); @@ -219,11 +221,10 @@ err = elf_errno(); if (err != 0) { - error_message(LIBELF_ERROR, - LIBelf_ERROR, elf_errmsg(err), prog); - error_message(NOT_MANIPULATED_ERROR, - PLAIN_ERROR, (char *)0, - prog, cur_file); + error_message(LIBELF_ERROR, LIBelf_ERROR, + elf_errmsg(err), prog); + error_message(NOT_MANIPULATED_ERROR, PLAIN_ERROR, (char *)0, + prog, cur_file); return (FAILURE); } @@ -242,52 +243,65 @@ static int process_file(Elf *elf, char *cur_file, Cmd_Info *cmd_info) { - int error = SUCCESS; - int x; - GElf_Ehdr ehdr; - size_t shnum; + int error = SUCCESS; + int x; + GElf_Ehdr ehdr; + size_t shnum; + file_state_t state; /* * Initialize */ if (gelf_getehdr(elf, &ehdr) == NULL) { - error_message(LIBELF_ERROR, - LIBelf_ERROR, elf_errmsg(-1), prog); + error_message(LIBELF_ERROR, LIBelf_ERROR, elf_errmsg(-1), prog); return (FAILURE); } if (elf_getshnum(elf, &shnum) == NULL) { - error_message(LIBELF_ERROR, - LIBelf_ERROR, elf_errmsg(-1), prog); + error_message(LIBELF_ERROR, LIBelf_ERROR, elf_errmsg(-1), prog); return (FAILURE); } - initialize(shnum, cmd_info); + /* Initialize per-file state */ + state.Sect_exists = 0; + state.notesegndx = -1; + state.notesctndx = -1; + state.b_e_seg_table = NULL; + state.sec_table = NULL; + state.off_table = 0; + state.nobits_table = NULL; + state.new_sec_string = NULL; - if (ehdr.e_phnum != 0) { - if (build_segment_table(elf, &ehdr) == FAILURE) - return (FAILURE); - } + initialize(shnum, cmd_info, &state); - if ((x = traverse_file(elf, &ehdr, cur_file, cmd_info)) == - FAILURE) { - error_message(WRN_MANIPULATED_ERROR, - PLAIN_ERROR, (char *)0, - prog, cur_file); + if ((ehdr.e_phnum != 0) && + (build_segment_table(elf, &ehdr, &state) == FAILURE)) { + x = error = FAILURE; + } else if ((x = traverse_file(elf, &ehdr, cur_file, + cmd_info, &state)) == FAILURE) { + error_message(WRN_MANIPULATED_ERROR, PLAIN_ERROR, (char *)0, + prog, cur_file); error = FAILURE; } else if (x != DONT_BUILD && x != FAILURE) { - post_process(cmd_info); - if (build_file(elf, &ehdr, cmd_info) == FAILURE) { - error_message(WRN_MANIPULATED_ERROR, - PLAIN_ERROR, (char *)0, - prog, cur_file); + post_process(cmd_info, &state); + if (build_file(elf, &ehdr, cmd_info, &state) == FAILURE) { + error_message(WRN_MANIPULATED_ERROR, PLAIN_ERROR, + (char *)0, prog, cur_file); error = FAILURE; } } - free(off_table); - free(sec_table); - free(nobits_table); + /* Release any dynamicaly allocated buffers */ + if (state.b_e_seg_table != NULL) + free(state.b_e_seg_table); + if (state.sec_table != NULL) + free(state.sec_table); + if (state.off_table != NULL) + free(state.off_table); + if (state.nobits_table != NULL) + free(state.nobits_table); + if (state.new_sec_string != NULL) + free(state.new_sec_string); if (x == DONT_BUILD) return (DONT_BUILD); @@ -296,7 +310,8 @@ } static int -traverse_file(Elf *elf, GElf_Ehdr * ehdr, char *cur_file, Cmd_Info *cmd_info) +traverse_file(Elf *elf, GElf_Ehdr * ehdr, char *cur_file, Cmd_Info *cmd_info, + file_state_t *state) { Elf_Scn * scn; Elf_Scn * temp_scn; @@ -310,38 +325,36 @@ unsigned int i, scn_index; size_t shstrndx, shnum; - Sect_exists = 0; + state->Sect_exists = 0; if (elf_getshnum(elf, &shnum) == NULL) { - error_message(LIBELF_ERROR, - LIBelf_ERROR, elf_errmsg(-1), prog); + error_message(LIBELF_ERROR, LIBelf_ERROR, elf_errmsg(-1), prog); return (FAILURE); } if (elf_getshstrndx(elf, &shstrndx) == NULL) { - error_message(LIBELF_ERROR, - LIBelf_ERROR, elf_errmsg(-1), prog); + error_message(LIBELF_ERROR, LIBelf_ERROR, elf_errmsg(-1), prog); return (FAILURE); } scn = 0; scn_index = 1; - sinfo = &sec_table[scn_index]; + sinfo = &state->sec_table[scn_index]; while ((scn = elf_nextscn(elf, scn)) != 0) { char *name; shdr = &(sinfo->shdr); if (gelf_getshdr(scn, shdr) == NULL) { error_message(NO_SECT_TABLE_ERROR, - LIBelf_ERROR, elf_errmsg(-1), - prog, cur_file); + LIBelf_ERROR, elf_errmsg(-1), prog, cur_file); return (FAILURE); - } else { - name = elf_strptr(elf, shstrndx, - (size_t)shdr->sh_name); - if (name == NULL) - name = "_@@@###"; } + /* + * Note: If the object has problems, name + * may be set to NULL by the following. + */ + name = elf_strptr(elf, shstrndx, (size_t)shdr->sh_name); + sinfo->scn = scn; sinfo->secno = scn_index; sinfo->osecno = scn_index; @@ -350,14 +363,14 @@ if (ehdr->e_phnum == 0) SET_LOC(sinfo->flags, NOSEG); else - SET_LOC(sinfo->flags, scn_location(scn, elf)); + SET_LOC(sinfo->flags, scn_location(scn, elf, state)); if (shdr->sh_type == SHT_GROUP) { - if (list_appendc(&cmd_info->sh_groups, sinfo) == 0) { - error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, prog); - mcs_exit(FAILURE); - } + if (list_appendc(&cmd_info->sh_groups, sinfo) == 0) { + error_message(MALLOC_ERROR, PLAIN_ERROR, + (char *)0, prog); + mcs_exit(FAILURE); + } } /* @@ -373,21 +386,21 @@ GElf_Shdr tmp_shdr; if (gelf_getshdr(temp_scn, &tmp_shdr) != NULL) { temp_name = elf_strptr(elf, shstrndx, - (size_t)tmp_shdr.sh_name); + (size_t)tmp_shdr.sh_name); sinfo->rel_name = temp_name; sinfo->rel_scn_index = shdr->sh_info; if (phnum == 0) sinfo->rel_loc = NOSEG; - else + else sinfo->rel_loc = - scn_location(temp_scn, elf); + scn_location(temp_scn, elf, state); } } data = 0; if ((data = elf_getdata(scn, data)) == NULL) { error_message(LIBELF_ERROR, - LIBelf_ERROR, elf_errmsg(-1), prog); + LIBelf_ERROR, elf_errmsg(-1), prog); return (FAILURE); } sinfo->data = data; @@ -396,14 +409,14 @@ * Check if this section is a candidate for * action to be processes. */ - if (sectcmp(name) == 0) { + if ((name != NULL) && (sectcmp(name) == 0)) { SET_CANDIDATE(sinfo->flags); /* * This flag just shows that there was a * candidate. */ - Sect_exists++; + state->Sect_exists++; } /* @@ -415,7 +428,7 @@ ((shdr->sh_type == SHT_SUNW_DEBUG) || (shdr->sh_type == SHT_SUNW_DEBUGSTR))) { SET_CANDIDATE(sinfo->flags); - Sect_exists++; + state->Sect_exists++; } @@ -425,25 +438,32 @@ if ((cmd_info->flags & zFLAG) && (shdr->sh_type == SHT_PROGBITS)) { SET_CANDIDATE(sinfo->flags); - Sect_exists++; + state->Sect_exists++; } x = GET_LOC(sinfo->flags); /* - * Remeber the note sections index so that we can - * reset the NOTE segments offset to point to it. + * Remember the note section index so that we can + * reset the NOTE segment offset to point to it. Depending + * on the operation being carried out, the note section may + * be assigned a new location in the resulting ELF + * image, and the program header needs to reflect that. * - * It may have been assigned a new location in the - * resulting output elf image. + * There can be multiple contiguous note sections in + * an object, referenced by a single NOTE segment. We + * want to be sure and remember the one referenced by + * the program header, and not one of the others. */ - if (shdr->sh_type == SHT_NOTE) - notesctndx = scn_index; + if ((shdr->sh_type == SHT_NOTE) && (state->notesctndx == -1) && + (state->notesegndx != -1) && + (state->b_e_seg_table[state->notesegndx].p_offset + == shdr->sh_offset)) + state->notesctndx = scn_index; if (x == IN || x == PRIOR) - off_table[scn_index] = - shdr->sh_offset; + state->off_table[scn_index] = shdr->sh_offset; if (shdr->sh_type == SHT_NOBITS) - nobits_table[scn_index] = 1; + state->nobits_table[scn_index] = 1; /* * If this section satisfies the condition, @@ -482,13 +502,13 @@ if (CHK_OPT(cmd_info, I_AM_STRIP) && SYM != 0) { GElf_Shdr tmp_shdr; - (void) gelf_getshdr(sec_table[SYM].scn, &tmp_shdr); - sec_table[SYM].secno = (GElf_Word)DELETED; + (void) gelf_getshdr(state->sec_table[SYM].scn, &tmp_shdr); + state->sec_table[SYM].secno = (GElf_Word)DELETED; ++(cmd_info->no_of_nulled); - if (Sect_exists == 0) - ++Sect_exists; - SET_ACTION(sec_table[SYM].flags, ACT_DELETE); - off_table[SYM] = 0; + if (state->Sect_exists == 0) + ++state->Sect_exists; + SET_ACTION(state->sec_table[SYM].flags, ACT_DELETE); + state->off_table[SYM] = 0; /* * Can I remove section header * string table ? @@ -496,14 +516,16 @@ if ((tmp_shdr.sh_link < shnum) && (tmp_shdr.sh_link != SHN_UNDEF) && (tmp_shdr.sh_link != shstrndx) && - (GET_LOC(sec_table[tmp_shdr.sh_link].flags) == AFTER)) { - sec_table[tmp_shdr.sh_link].secno = (GElf_Word)DELETED; + (GET_LOC(state->sec_table[tmp_shdr.sh_link].flags) == + AFTER)) { + state->sec_table[tmp_shdr.sh_link].secno = + (GElf_Word)DELETED; ++(cmd_info->no_of_nulled); - if (Sect_exists == 0) - ++Sect_exists; - SET_ACTION(sec_table[tmp_shdr.sh_link].flags,\ - ACT_DELETE); - off_table[tmp_shdr.sh_link] = 0; + if (state->Sect_exists == 0) + ++state->Sect_exists; + SET_ACTION(state->sec_table[tmp_shdr.sh_link].flags, + ACT_DELETE); + state->off_table[tmp_shdr.sh_link] = 0; } } @@ -518,16 +540,16 @@ /* * I might need to add a new section. Check it. */ - if (Sect_exists == 0 && CHK_OPT(cmd_info, aFLAG)) { + if (state->Sect_exists == 0 && CHK_OPT(cmd_info, aFLAG)) { int act = 0; - new_sec_string = calloc(1, cmd_info->str_size + 1); - if (new_sec_string == NULL) + state->new_sec_string = calloc(1, cmd_info->str_size + 1); + if (state->new_sec_string == NULL) return (FAILURE); for (act = 0; act < actmax; act++) { if (Action[act].a_action == ACT_APPEND) { - (void) strcat(new_sec_string, - Action[act].a_string); - (void) strcat(new_sec_string, "\n"); + (void) strcat(state->new_sec_string, + Action[act].a_string); + (void) strcat(state->new_sec_string, "\n"); cmd_info->no_of_append = 1; } } @@ -537,7 +559,7 @@ * If I did not append any new sections, and I did not * modify/delete any sections, then just report so. */ - if ((Sect_exists == 0 && cmd_info->no_of_append == 0) || + if ((state->Sect_exists == 0 && cmd_info->no_of_append == 0) || !CHK_OPT(cmd_info, MIGHT_CHG)) return (DONT_BUILD); @@ -545,7 +567,7 @@ * Found at least one section which was processed. * Deleted or Appended or Compressed. */ - if (Sect_exists) { + if (state->Sect_exists) { /* * First, handle the deleted sections. */ @@ -558,7 +580,7 @@ * Handle relocation/target * sections. */ - sinfo = &(sec_table[0]); + sinfo = &(state->sec_table[0]); for (i = 1; i < shnum; i++) { sinfo++; rel_idx = sinfo->rel_scn_index; @@ -574,15 +596,15 @@ (sinfo->secno == (GElf_Word)NULLED)) && sinfo->rel_loc != IN) { - if (GET_LOC(sec_table[rel_idx].flags) == - PRIOR) - sec_table[rel_idx].secno = - (GElf_Word)NULLED; + if (GET_LOC(state-> + sec_table[rel_idx].flags) == PRIOR) + state->sec_table[rel_idx]. + secno = (GElf_Word)NULLED; else - sec_table[rel_idx].secno = - (GElf_Word)DELETED; - SET_ACTION(sec_table[rel_idx].flags,\ - ACT_DELETE); + state->sec_table[rel_idx]. + secno = (GElf_Word)DELETED; + SET_ACTION(state->sec_table[rel_idx]. + flags, ACT_DELETE); } /* @@ -590,50 +612,51 @@ * removed or nulled. If so, let me try to * remove my self. */ - if (((sec_table[rel_idx].secno == + if (((state->sec_table[rel_idx].secno == (GElf_Word)DELETED) || - (sec_table[rel_idx].secno == + (state->sec_table[rel_idx].secno == (GElf_Word)NULLED)) && (GET_LOC(sinfo->flags) != IN)) { if (GET_LOC(sinfo->flags) == PRIOR) sinfo->secno = - (GElf_Word)NULLED; + (GElf_Word)NULLED; else sinfo->secno = - (GElf_Word)DELETED; - SET_ACTION(sinfo->flags,\ - ACT_DELETE); + (GElf_Word)DELETED; + SET_ACTION(sinfo->flags, ACT_DELETE); } } /* * Now, take care of DELETED sections */ - sinfo = &(sec_table[1]); + sinfo = &(state->sec_table[1]); for (i = 1; i < shnum; i++) { - shdr = &(sinfo->shdr); - if (sinfo->secno == (GElf_Word)DELETED) { - acc++; - /* - * The SHT_GROUP section which this section - * is a member may be able to be removed. - * See post_process(). - */ - if (shdr->sh_flags & SHF_GROUP) - cmd_info->flags |= SHF_GROUP_DEL; - } else { - /* - * The data buffer of SHT_GROUP this section - * is a member needs to be updated. - * See post_process(). - */ - sinfo->secno -= acc; - if ((shdr->sh_flags & - SHF_GROUP) && (acc != 0)) - cmd_info->flags |= SHF_GROUP_MOVE; - } - sinfo++; + shdr = &(sinfo->shdr); + if (sinfo->secno == (GElf_Word)DELETED) { + acc++; + /* + * The SHT_GROUP section which this + * section is a member may be able + * to be removed. See post_process(). + */ + if (shdr->sh_flags & SHF_GROUP) + cmd_info->flags |= + SHF_GROUP_DEL; + } else { + /* + * The data buffer of SHT_GROUP this + * section is a member needs to be + * updated. See post_process(). + */ + sinfo->secno -= acc; + if ((shdr->sh_flags & SHF_GROUP) && + (acc != 0)) + cmd_info->flags |= + SHF_GROUP_MOVE; + } + sinfo++; } } } @@ -646,7 +669,8 @@ } static int -build_file(Elf *src_elf, GElf_Ehdr *src_ehdr, Cmd_Info *cmd_info) +build_file(Elf *src_elf, GElf_Ehdr *src_ehdr, Cmd_Info *cmd_info, + file_state_t *state) { Elf_Scn *src_scn; Elf_Scn *dst_scn; @@ -668,35 +692,30 @@ if (elf_getshnum(src_elf, &shnum) == NULL) { - error_message(LIBELF_ERROR, - LIBelf_ERROR, elf_errmsg(-1), prog); + error_message(LIBELF_ERROR, LIBelf_ERROR, elf_errmsg(-1), prog); return (FAILURE); } if (elf_getshstrndx(src_elf, &shstrndx) == NULL) { - error_message(LIBELF_ERROR, - LIBelf_ERROR, elf_errmsg(-1), prog); + error_message(LIBELF_ERROR, LIBelf_ERROR, elf_errmsg(-1), prog); return (FAILURE); } - if ((fdtmp = open(elftmpfile, O_RDWR | - O_TRUNC | O_CREAT, (mode_t)0666)) == -1) { - error_message(OPEN_TEMP_ERROR, - SYSTEM_ERROR, strerror(errno), - prog, elftmpfile); + if ((fdtmp = open(elftmpfile, O_RDWR | O_TRUNC | O_CREAT, + (mode_t)0666)) == -1) { + error_message(OPEN_TEMP_ERROR, SYSTEM_ERROR, strerror(errno), + prog, elftmpfile); return (FAILURE); } if ((dst_elf = elf_begin(fdtmp, ELF_C_WRITE, (Elf *) 0)) == NULL) { - error_message(READ_ERROR, - LIBelf_ERROR, elf_errmsg(-1), - prog, elftmpfile); + error_message(READ_ERROR, LIBelf_ERROR, elf_errmsg(-1), + prog, elftmpfile); (void) close(fdtmp); return (FAILURE); } if (gelf_newehdr(dst_elf, gelf_getclass(src_elf)) == NULL) { - error_message(LIBELF_ERROR, - LIBelf_ERROR, elf_errmsg(-1), prog); + error_message(LIBELF_ERROR, LIBelf_ERROR, elf_errmsg(-1), prog); return (FAILURE); } @@ -709,7 +728,7 @@ * remove the reference to it from the ELF header. */ if ((shstrndx != SHN_UNDEF) && - (sec_table[shstrndx].secno == (GElf_Word)DELETED)) + (state->sec_table[shstrndx].secno == (GElf_Word)DELETED)) dst_ehdr.e_shstrndx = SHN_UNDEF; /* @@ -723,8 +742,8 @@ (void) elf_flagelf(dst_elf, ELF_C_SET, ELF_F_LAYOUT); if (gelf_newphdr(dst_elf, src_ehdr->e_phnum) == NULL) { - error_message(LIBELF_ERROR, - LIBelf_ERROR, elf_errmsg(-1), prog); + error_message(LIBELF_ERROR, LIBelf_ERROR, + elf_errmsg(-1), prog); return (FAILURE); } @@ -741,20 +760,20 @@ (void) gelf_update_phdr(dst_elf, (int)x, &dst); } - x = location(dst_ehdr.e_phoff, 0, src_elf); + x = location(dst_ehdr.e_phoff, 0, src_elf, state); if (x == AFTER) new_offset = (GElf_Off)src_ehdr->e_ehsize; } scn_no = 1; - while ((src_scn = sec_table[scn_no].scn) != (Elf_Scn *) -1) { - info = &sec_table[scn_no]; + while ((src_scn = state->sec_table[scn_no].scn) != (Elf_Scn *) -1) { + info = &state->sec_table[scn_no]; /* If section should be copied to new file NOW */ if ((info->secno != (GElf_Word)DELETED) && info->secno <= scn_no) { if ((dst_scn = elf_newscn(dst_elf)) == NULL) { error_message(LIBELF_ERROR, - LIBelf_ERROR, elf_errmsg(-1), prog); + LIBelf_ERROR, elf_errmsg(-1), prog); return (FAILURE); } (void) gelf_getshdr(dst_scn, &dst_shdr); @@ -769,27 +788,28 @@ if ((src_shdr.sh_link >= shnum) || (src_shdr.sh_link == 0)) dst_shdr.sh_link = src_shdr.sh_link; - else if ((int)sec_table[src_shdr.sh_link].secno < 0) + else if ((int)state->sec_table[src_shdr.sh_link].secno < + 0) dst_shdr.sh_link = 0; else dst_shdr.sh_link = - sec_table[src_shdr.sh_link].secno; + state->sec_table[src_shdr.sh_link].secno; if ((src_shdr.sh_type == SHT_REL) || (src_shdr.sh_type == SHT_RELA)) { if ((src_shdr.sh_info >= shnum) || - ((int)sec_table[src_shdr. + ((int)state->sec_table[src_shdr. sh_info].secno < 0)) dst_shdr.sh_info = 0; else - dst_shdr.sh_info = + dst_shdr.sh_info = state-> sec_table[src_shdr.sh_info].secno; } - data = sec_table[scn_no].data; + data = state->sec_table[scn_no].data; if ((elf_data = elf_newdata(dst_scn)) == NULL) { error_message(LIBELF_ERROR, - LIBelf_ERROR, elf_errmsg(-1), prog); + LIBelf_ERROR, elf_errmsg(-1), prog); return (FAILURE); } *elf_data = *data; @@ -811,10 +831,10 @@ no_of_symbols = src_shdr.sh_size / src_shdr.sh_entsize; new_sym = malloc(no_of_symbols * - src_shdr.sh_entsize); + src_shdr.sh_entsize); if (new_sym == NULL) { error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, prog); + PLAIN_ERROR, (char *)0, prog); mcs_exit(FAILURE); } @@ -828,15 +848,17 @@ if ((csym.st_shndx < SHN_LORESERVE) && (csym.st_shndx != SHN_UNDEF)) { section_info_table *i; - i = &sec_table[csym.st_shndx]; + i = &state-> + sec_table[csym.st_shndx]; if (((int)i->secno != DELETED) && - ((int)i->secno != NULLED)) + ((int)i->secno != NULLED)) { csym.st_shndx = i->secno; - else { + } else { + /* BEGIN CSTYLED */ if (src_shdr.sh_type == - SHT_SYMTAB) + SHT_SYMTAB) { /* * The section which * this * symbol relates @@ -847,7 +869,7 @@ * to 1. */ csym.st_shndx = 1; - else { + } else { /* * If this is in a * .dynsym, NULL it out. @@ -860,6 +882,7 @@ csym.st_other = 0; csym.st_shndx = 0; } + /* END CSTYLED */ } } @@ -880,18 +903,18 @@ entcnt = src_shdr.sh_size / src_shdr.sh_entsize; oldshndx = data->d_buf; - newshndx = malloc(entcnt * - src_shdr.sh_entsize); + newshndx = malloc(entcnt * src_shdr.sh_entsize); if (newshndx == NULL) { error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, prog); + PLAIN_ERROR, (char *)0, prog); mcs_exit(FAILURE); } elf_data->d_buf = (void *)newshndx; for (c = 0; c < entcnt; c++) { if (oldshndx[c] != SHN_UNDEF) { section_info_table *i; - i = &sec_table[oldshndx[c]]; + i = &state-> + sec_table[oldshndx[c]]; if (((int)i->secno != DELETED) && ((int)i->secno != NULLED)) @@ -931,36 +954,35 @@ * or there are no segments. * It is safe to update this section. */ - data = sec_table[scn_no].mdata; + data = state->sec_table[scn_no].mdata; *elf_data = *data; dst_shdr.sh_size = elf_data->d_size; } } /* add new section name to shstrtab? */ - else if (!Sect_exists && - (new_sec_string != NULL) && + else if (!state->Sect_exists && + (state->new_sec_string != NULL) && (scn_no == shstrndx) && (dst_shdr.sh_type == SHT_STRTAB) && ((src_ehdr->e_phnum == 0) || - ((x = scn_location(dst_scn, dst_elf)) != IN) || + ((x = scn_location(dst_scn, dst_elf, state)) + != IN) || (x != PRIOR))) { size_t sect_len; sect_len = strlen(SECT_NAME); if ((elf_data->d_buf = - malloc((dst_shdr.sh_size + - sect_len + 1))) == NULL) { + malloc((dst_shdr.sh_size + + sect_len + 1))) == NULL) { error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, prog); + PLAIN_ERROR, (char *)0, prog); mcs_exit(FAILURE); } /* put original data plus new data in section */ (void) memcpy(elf_data->d_buf, - data->d_buf, data->d_size); + data->d_buf, data->d_size); (void) memcpy(&((char *)elf_data->d_buf) - [data->d_size], - SECT_NAME, - sect_len + 1); + [data->d_size], SECT_NAME, sect_len + 1); /* LINTED */ new_sh_name = (int)dst_shdr.sh_size; dst_shdr.sh_size += sect_len + 1; @@ -974,21 +996,23 @@ /* * Compute section offset. */ - if (off_table[scn_no] == 0) { + if (state->off_table[scn_no] == 0) { if (dst_shdr.sh_addralign != 0) { r = new_offset % dst_shdr.sh_addralign; if (r) - new_offset += - dst_shdr.sh_addralign - r; + new_offset += + dst_shdr. + sh_addralign - r; } dst_shdr.sh_offset = new_offset; elf_data->d_off = 0; } else { - if (nobits_table[scn_no] == 0) - new_offset = off_table[scn_no]; + if (state->nobits_table[scn_no] == 0) + new_offset = + state->off_table[scn_no]; } - if (nobits_table[scn_no] == 0) + if (state->nobits_table[scn_no] == 0) new_offset += dst_shdr.sh_size; } @@ -1001,12 +1025,12 @@ /* * This is the real new section. */ - if (!Sect_exists && new_sec_string != NULL) { + if (!state->Sect_exists && state->new_sec_string != NULL) { size_t string_size; - string_size = strlen(new_sec_string) + 1; + string_size = strlen(state->new_sec_string) + 1; if ((dst_scn = elf_newscn(dst_elf)) == NULL) { error_message(LIBELF_ERROR, - LIBelf_ERROR, elf_errmsg(-1), prog); + LIBelf_ERROR, elf_errmsg(-1), prog); return (FAILURE); } (void) gelf_getshdr(dst_scn, &dst_shdr); @@ -1028,19 +1052,18 @@ if ((elf_data = elf_newdata(dst_scn)) == NULL) { error_message(LIBELF_ERROR, - LIBelf_ERROR, elf_errmsg(-1), prog); + LIBelf_ERROR, elf_errmsg(-1), prog); return (FAILURE); } elf_data->d_size = string_size + 1; if ((elf_data->d_buf = (char *) calloc(1, string_size + 1)) == NULL) { error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, - prog); + PLAIN_ERROR, (char *)0, prog); mcs_exit(FAILURE); } (void) memcpy(&((char *)elf_data->d_buf)[1], - new_sec_string, string_size); + state->new_sec_string, string_size); elf_data->d_align = 1; new_offset += string_size + 1; } @@ -1051,7 +1074,7 @@ */ if (cmd_info->no_of_moved != 0) { int cnt; - info = &sec_table[0]; + info = &state->sec_table[0]; for (cnt = 0; cnt < shnum; cnt++, info++) { if ((GET_MOVING(info->flags)) == 0) @@ -1060,22 +1083,22 @@ if ((src_scn = elf_getscn(src_elf, info->osecno)) == NULL) { error_message(LIBELF_ERROR, - LIBelf_ERROR, elf_errmsg(-1), prog); + LIBelf_ERROR, elf_errmsg(-1), prog); return (FAILURE); } if (gelf_getshdr(src_scn, &src_shdr) == NULL) { error_message(LIBELF_ERROR, - LIBelf_ERROR, elf_errmsg(-1), prog); + LIBelf_ERROR, elf_errmsg(-1), prog); return (FAILURE); } if ((dst_scn = elf_newscn(dst_elf)) == NULL) { error_message(LIBELF_ERROR, - LIBelf_ERROR, elf_errmsg(-1), prog); + LIBelf_ERROR, elf_errmsg(-1), prog); return (FAILURE); } if (gelf_getshdr(dst_scn, &dst_shdr) == NULL) { error_message(LIBELF_ERROR, - LIBelf_ERROR, elf_errmsg(-1), prog); + LIBelf_ERROR, elf_errmsg(-1), prog); return (FAILURE); } dst_shdr = src_shdr; @@ -1090,18 +1113,18 @@ dst_shdr.sh_link = src_shdr.sh_link; else dst_shdr.sh_link = - sec_table[src_shdr.sh_link].osecno; + state->sec_table[src_shdr.sh_link].osecno; if ((shnum >= src_shdr.sh_info) || (src_shdr.sh_info == 0)) dst_shdr.sh_info = src_shdr.sh_info; else dst_shdr.sh_info = - sec_table[src_shdr.sh_info].osecno; + state->sec_table[src_shdr.sh_info].osecno; (void) gelf_update_shdr(dst_scn, &dst_shdr); if ((elf_data = elf_newdata(dst_scn)) == NULL) { error_message(LIBELF_ERROR, - LIBelf_ERROR, elf_errmsg(-1), prog); + LIBelf_ERROR, elf_errmsg(-1), prog); return (FAILURE); } (void) memcpy(elf_data, data, sizeof (Elf_Data)); @@ -1115,10 +1138,10 @@ * as a result of deleted sections, update the ehdr->e_shstrndx. */ if ((shstrndx > 0) && (shnum > 0) && - (sec_table[shstrndx].secno < shnum)) { - if (sec_table[shstrndx].secno < SHN_LORESERVE) { + (state->sec_table[shstrndx].secno < shnum)) { + if (state->sec_table[shstrndx].secno < SHN_LORESERVE) { dst_ehdr.e_shstrndx = - sec_table[dst_ehdr.e_shstrndx].secno; + state->sec_table[dst_ehdr.e_shstrndx].secno; } else { Elf_Scn *_scn; GElf_Shdr shdr0; @@ -1130,11 +1153,11 @@ dst_ehdr.e_shstrndx = SHN_XINDEX; if ((_scn = elf_getscn(dst_elf, 0)) == NULL) { error_message(LIBELF_ERROR, - LIBelf_ERROR, elf_errmsg(-1), prog); + LIBelf_ERROR, elf_errmsg(-1), prog); return (FAILURE); } (void) gelf_getshdr(_scn, &shdr0); - shdr0.sh_link = sec_table[shstrndx].secno; + shdr0.sh_link = state->sec_table[shstrndx].secno; (void) gelf_update_shdr(_scn, &shdr0); } } @@ -1143,26 +1166,24 @@ size_t align = gelf_fsize(dst_elf, ELF_T_ADDR, 1, EV_CURRENT); /* UPDATE location of program header table */ - if (location(dst_ehdr.e_phoff, 0, dst_elf) == AFTER) { + if (location(dst_ehdr.e_phoff, 0, dst_elf, state) == AFTER) { r = new_offset % align; if (r) new_offset += align - r; dst_ehdr.e_phoff = new_offset; - new_offset += dst_ehdr.e_phnum - * dst_ehdr.e_phentsize; + new_offset += dst_ehdr.e_phnum * dst_ehdr.e_phentsize; } /* UPDATE location of section header table */ - if ((location(dst_ehdr.e_shoff, 0, src_elf) == AFTER) || - ((location(dst_ehdr.e_shoff, 0, src_elf) == PRIOR) && - (!Sect_exists && new_sec_string != NULL))) { + if ((location(dst_ehdr.e_shoff, 0, src_elf, state) == AFTER) || + ((location(dst_ehdr.e_shoff, 0, src_elf, state) == PRIOR) && + (!state->Sect_exists && state->new_sec_string != NULL))) { r = new_offset % align; if (r) new_offset += align - r; dst_ehdr.e_shoff = new_offset; } - free(b_e_seg_table); /* * The NOTE segment is the one segment whos @@ -1170,23 +1191,23 @@ * Make sure that the NOTE segments offset points * to the .note section. */ - if ((notesegndx != -1) && (notesctndx != -1) && - (sec_table[notesctndx].secno)) { + if ((state->notesegndx != -1) && (state->notesctndx != -1) && + (state->sec_table[state->notesctndx].secno)) { Elf_Scn * notescn; GElf_Shdr nshdr; notescn = elf_getscn(dst_elf, - sec_table[notesctndx].secno); + state->sec_table[state->notesctndx].secno); (void) gelf_getshdr(notescn, &nshdr); if (gelf_getclass(dst_elf) == ELFCLASS32) { Elf32_Phdr * ph = elf32_getphdr(dst_elf) + - notesegndx; + state->notesegndx; /* LINTED */ ph->p_offset = (Elf32_Off)nshdr.sh_offset; } else { Elf64_Phdr * ph = elf64_getphdr(dst_elf) + - notesegndx; + state->notesegndx; ph->p_offset = (Elf64_Off)nshdr.sh_offset; } } @@ -1195,8 +1216,7 @@ /* copy ehdr changes back into real ehdr */ (void) gelf_update_ehdr(dst_elf, &dst_ehdr); if (elf_update(dst_elf, ELF_C_WRITE) < 0) { - error_message(LIBELF_ERROR, - LIBelf_ERROR, elf_errmsg(-1), prog); + error_message(LIBELF_ERROR, LIBelf_ERROR, elf_errmsg(-1), prog); return (FAILURE); } @@ -1209,15 +1229,14 @@ * Search through PHT saving the beginning and ending segment offsets */ static int -build_segment_table(Elf * elf, GElf_Ehdr * ehdr) +build_segment_table(Elf * elf, GElf_Ehdr * ehdr, file_state_t *state) { unsigned int i; - if ((b_e_seg_table = (Seg_Table *) - calloc(ehdr->e_phnum, sizeof (Seg_Table))) == NULL) { - error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, - prog); + state->b_e_seg_table = (Seg_Table *) + calloc(ehdr->e_phnum, sizeof (Seg_Table)); + if (state->b_e_seg_table == NULL) { + error_message(MALLOC_ERROR, PLAIN_ERROR, (char *)0, prog); mcs_exit(FAILURE); } @@ -1231,11 +1250,11 @@ * re-set it's p_offset later if needed. */ if (ph.p_type == PT_NOTE) - notesegndx = i; + state->notesegndx = i; - b_e_seg_table[i].p_offset = ph.p_offset; - b_e_seg_table[i].p_memsz = ph.p_offset + ph.p_memsz; - b_e_seg_table[i].p_filesz = ph.p_offset + ph.p_filesz; + state->b_e_seg_table[i].p_offset = ph.p_offset; + state->b_e_seg_table[i].p_memsz = ph.p_offset + ph.p_memsz; + state->b_e_seg_table[i].p_filesz = ph.p_offset + ph.p_filesz; } return (SUCCESS); } @@ -1253,9 +1272,8 @@ struct stat stbuf; if ((fdtmp3 = open(elftmpfile, O_RDONLY)) == -1) { - error_message(OPEN_TEMP_ERROR, - SYSTEM_ERROR, strerror(errno), - prog, elftmpfile); + error_message(OPEN_TEMP_ERROR, SYSTEM_ERROR, strerror(errno), + prog, elftmpfile); mcs_exit(FAILURE); } @@ -1263,33 +1281,26 @@ if ((buf = malloc(ROUNDUP(stbuf.st_size))) == NULL) { - error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, - prog); + error_message(MALLOC_ERROR, PLAIN_ERROR, (char *)0, prog); mcs_exit(FAILURE); } if (read(fdtmp3, buf, stbuf.st_size) != stbuf.st_size) { - error_message(READ_MANI_ERROR, - SYSTEM_ERROR, strerror(errno), - prog, elftmpfile, cur_file); + error_message(READ_MANI_ERROR, SYSTEM_ERROR, strerror(errno), + prog, elftmpfile, cur_file); mcs_exit(FAILURE); } - (void) sprintf(mem_header_buf, FORMAT, - mem_header->ar_rawname, - mem_header->ar_date, - (unsigned)mem_header->ar_uid, - (unsigned)mem_header->ar_gid, - (unsigned)mem_header->ar_mode, - stbuf.st_size, ARFMAG); + (void) sprintf(mem_header_buf, FORMAT, mem_header->ar_rawname, + mem_header->ar_date, (unsigned)mem_header->ar_uid, + (unsigned)mem_header->ar_gid, (unsigned)mem_header->ar_mode, + stbuf.st_size, ARFMAG); if (write(fdartmp, mem_header_buf, (unsigned)sizeof (struct ar_hdr)) != (unsigned)sizeof (struct ar_hdr)) { - error_message(WRITE_MANI_ERROR, - SYSTEM_ERROR, strerror(errno), - prog, elftmpfile, cur_file); + error_message(WRITE_MANI_ERROR, SYSTEM_ERROR, strerror(errno), + prog, elftmpfile, cur_file); mcs_exit(FAILURE); } @@ -1297,15 +1308,13 @@ buf[stbuf.st_size] = '\n'; if (write(fdartmp, buf, (size_t)ROUNDUP(stbuf.st_size)) != (size_t)ROUNDUP(stbuf.st_size)) { - error_message(WRITE_MANI_ERROR, - SYSTEM_ERROR, strerror(errno), - prog, elftmpfile, cur_file); + error_message(WRITE_MANI_ERROR, SYSTEM_ERROR, + strerror(errno), prog, elftmpfile, cur_file); mcs_exit(FAILURE); } } else if (write(fdartmp, buf, stbuf.st_size) != stbuf.st_size) { - error_message(WRITE_MANI_ERROR, - SYSTEM_ERROR, strerror(errno), - prog, elftmpfile, cur_file); + error_message(WRITE_MANI_ERROR, SYSTEM_ERROR, + strerror(errno), prog, elftmpfile, cur_file); mcs_exit(FAILURE); } free(buf); @@ -1325,78 +1334,67 @@ char *file_buf; if (strcmp(mem_header->ar_name, "/") != 0) { - (void) sprintf(mem_header_buf, FORMAT, - mem_header->ar_rawname, - mem_header->ar_date, - (unsigned)mem_header->ar_uid, - (unsigned)mem_header->ar_gid, - (unsigned)mem_header->ar_mode, - mem_header->ar_size, ARFMAG); + (void) sprintf(mem_header_buf, FORMAT, mem_header->ar_rawname, + mem_header->ar_date, (unsigned)mem_header->ar_uid, + (unsigned)mem_header->ar_gid, (unsigned)mem_header->ar_mode, + mem_header->ar_size, ARFMAG); if (write(fdartmp, mem_header_buf, sizeof (struct ar_hdr)) != sizeof (struct ar_hdr)) { - error_message(WRITE_MANI_ERROR, - SYSTEM_ERROR, strerror(errno), - prog, cur_file); + error_message(WRITE_MANI_ERROR, SYSTEM_ERROR, + strerror(errno), prog, cur_file); mcs_exit(FAILURE); } if ((file_buf = malloc(ROUNDUP(mem_header->ar_size))) == NULL) { - error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, - prog); + error_message(MALLOC_ERROR, PLAIN_ERROR, (char *)0, + prog); mcs_exit(FAILURE); } if (lseek(fd, elf_getbase(elf), 0) != elf_getbase(elf)) { - error_message(WRITE_MANI_ERROR, - prog, cur_file); + error_message(WRITE_MANI_ERROR, prog, cur_file); mcs_exit(FAILURE); } if (read(fd, file_buf, (size_t)ROUNDUP(mem_header->ar_size)) != (size_t)ROUNDUP(mem_header->ar_size)) { - error_message(READ_MANI_ERROR, - SYSTEM_ERROR, strerror(errno), - prog, cur_file); + error_message(READ_MANI_ERROR, SYSTEM_ERROR, + strerror(errno), prog, cur_file); mcs_exit(FAILURE); } if (write(fdartmp, file_buf, (size_t)ROUNDUP(mem_header->ar_size)) != (size_t)ROUNDUP(mem_header->ar_size)) { - error_message(WRITE_MANI_ERROR, - SYSTEM_ERROR, strerror(errno), - prog, cur_file); + error_message(WRITE_MANI_ERROR, SYSTEM_ERROR, + strerror(errno), prog, cur_file); mcs_exit(FAILURE); } free(file_buf); } else if (CHK_OPT(cmd_info, MIGHT_CHG)) { - error_message(SYM_TAB_AR_ERROR, - PLAIN_ERROR, (char *)0, - prog, cur_file); - error_message(EXEC_AR_ERROR, - PLAIN_ERROR, (char *)0, - cur_file); + error_message(SYM_TAB_AR_ERROR, PLAIN_ERROR, (char *)0, + prog, cur_file); + error_message(EXEC_AR_ERROR, PLAIN_ERROR, (char *)0, cur_file); } } static void copy_file(int ofd, char *fname, char *temp_file_name) { - int i; - int fdtmp2; - struct stat stbuf; - char *buf; + enum { MMAP_USED, MMAP_UNUSED } mmap_status; + int i; + int fdtmp2; + struct stat stbuf; + char *buf; for (i = 0; signum[i]; i++) /* started writing, cannot interrupt */ (void) signal(signum[i], SIG_IGN); if ((fdtmp2 = open(temp_file_name, O_RDONLY)) == -1) { - error_message(OPEN_TEMP_ERROR, - SYSTEM_ERROR, strerror(errno), - prog, temp_file_name); + error_message(OPEN_TEMP_ERROR, SYSTEM_ERROR, strerror(errno), + prog, temp_file_name); mcs_exit(FAILURE); } @@ -1407,49 +1405,44 @@ * First try mmap()'ing. If mmap() fails, * then use the malloc() and read(). */ - i = MMAP_USED; - if ((buf = (char *)mmap(0, stbuf.st_size, - PROT_READ, MAP_SHARED, fdtmp2, 0)) == (caddr_t)-1) { + mmap_status = MMAP_USED; + buf = (char *)mmap(0, stbuf.st_size, PROT_READ, MAP_SHARED, fdtmp2, 0); + if (buf == (caddr_t)-1) { if ((buf = malloc(stbuf.st_size * sizeof (char))) == NULL) { - error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, - prog); + error_message(MALLOC_ERROR, PLAIN_ERROR, (char *)0, + prog); mcs_exit(FAILURE); } if (read(fdtmp2, buf, stbuf.st_size) != stbuf.st_size) { - error_message(READ_SYS_ERROR, - SYSTEM_ERROR, strerror(errno), - prog, temp_file_name); + error_message(READ_SYS_ERROR, SYSTEM_ERROR, + strerror(errno), prog, temp_file_name); mcs_exit(FAILURE); } - i = MMAP_UNUSED; + mmap_status = MMAP_UNUSED; } if (ftruncate(ofd, 0) == -1) { - error_message(WRITE_MANI_ERROR2, - SYSTEM_ERROR, strerror(errno), - prog, fname); + error_message(WRITE_MANI_ERROR2, SYSTEM_ERROR, strerror(errno), + prog, fname); mcs_exit(FAILURE); } if (lseek(ofd, 0, SEEK_SET) == -1) { - error_message(WRITE_MANI_ERROR2, - SYSTEM_ERROR, strerror(errno), - prog, fname); + error_message(WRITE_MANI_ERROR2, SYSTEM_ERROR, strerror(errno), + prog, fname); mcs_exit(FAILURE); } if ((write(ofd, buf, stbuf.st_size)) != stbuf.st_size) { - error_message(WRITE_MANI_ERROR2, - SYSTEM_ERROR, strerror(errno), - prog, fname); + error_message(WRITE_MANI_ERROR2, SYSTEM_ERROR, strerror(errno), + prog, fname); mcs_exit(FAILURE); } /* * clean */ - if (i == MMAP_USED) + if (mmap_status == MMAP_USED) (void) munmap(buf, stbuf.st_size); else free(buf); @@ -1458,7 +1451,7 @@ } static uint64_t -location(int64_t offset, int mem_search, Elf * elf) +location(int64_t offset, int mem_search, Elf * elf, file_state_t *state) { int i; uint64_t upper; @@ -1468,20 +1461,20 @@ for (i = 0; i < ehdr.e_phnum; i++) { if (mem_search) - upper = b_e_seg_table[i].p_memsz; + upper = state->b_e_seg_table[i].p_memsz; else - upper = b_e_seg_table[i].p_filesz; - if ((offset >= b_e_seg_table[i].p_offset) && + upper = state->b_e_seg_table[i].p_filesz; + if ((offset >= state->b_e_seg_table[i].p_offset) && (offset <= upper)) return (IN); - else if (offset < b_e_seg_table[i].p_offset) + else if (offset < state->b_e_seg_table[i].p_offset) return (PRIOR); } return (AFTER); } static uint64_t -scn_location(Elf_Scn * scn, Elf * elf) +scn_location(Elf_Scn * scn, Elf * elf, file_state_t *state) { GElf_Shdr shdr; @@ -1492,45 +1485,38 @@ * virtual address then it is not part of a mapped segment. */ if (shdr.sh_addr == 0) - return (location(shdr.sh_offset + shdr.sh_size, 0, elf)); + return (location(shdr.sh_offset + shdr.sh_size, 0, elf, state)); - return (location(shdr.sh_offset + shdr.sh_size, 1, elf)); + return (location(shdr.sh_offset + shdr.sh_size, 1, elf, state)); } static void -initialize(int shnum, Cmd_Info *cmd_info) +initialize(int shnum, Cmd_Info *cmd_info, file_state_t *state) { /* * Initialize command info */ cmd_info->no_of_append = cmd_info->no_of_delete = - cmd_info->no_of_nulled = cmd_info->no_of_compressed = - cmd_info->no_of_moved = 0; + cmd_info->no_of_nulled = cmd_info->no_of_compressed = + cmd_info->no_of_moved = 0; cmd_info->sh_groups.head = cmd_info->sh_groups.tail = 0; - if ((sec_table = (section_info_table *) - calloc(shnum + 1, - sizeof (section_info_table))) == NULL) { - error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, - prog); + state->sec_table = (section_info_table *) + calloc(shnum + 1, sizeof (section_info_table)); + if (state->sec_table == NULL) { + error_message(MALLOC_ERROR, PLAIN_ERROR, (char *)0, prog); exit(FAILURE); } - if ((off_table = (int64_t *) - calloc(shnum, - sizeof (int64_t))) == NULL) { - error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, - prog); + state->off_table = (int64_t *)calloc(shnum, sizeof (int64_t)); + if (state->off_table == NULL) { + error_message(MALLOC_ERROR, PLAIN_ERROR, (char *)0, prog); exit(FAILURE); } - if ((nobits_table = (int64_t *) - calloc(shnum, sizeof (int64_t))) == NULL) { - error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, - prog); + state->nobits_table = (int64_t *)calloc(shnum, sizeof (int64_t)); + if (state->nobits_table == NULL) { + error_message(MALLOC_ERROR, PLAIN_ERROR, (char *)0, prog); exit(FAILURE); } } @@ -1538,8 +1524,8 @@ /* * Update the contents of SHT_GROUP if needed */ -void -post_process(Cmd_Info *cmd_info) +static void +post_process(Cmd_Info *cmd_info, file_state_t *state) { Listnode * lnp, *plnp; section_info_table * sinfo; @@ -1568,7 +1554,7 @@ grpcnt = 0; grpdata = (Word *)(sinfo->data->d_buf); for (i = 1; i < num; i++) { - if (sec_table[grpdata[i]].secno != + if (state->sec_table[grpdata[i]].secno != (GElf_Word)DELETED) grpcnt++; } @@ -1593,8 +1579,8 @@ sno = 1; sno2 = 1; - while (sec_table[sno].scn != (Elf_Scn *)-1) { - sinfo = &sec_table[sno]; + while (state->sec_table[sno].scn != (Elf_Scn *)-1) { + sinfo = &state->sec_table[sno]; if (sinfo->secno != (GElf_Word) DELETED) sinfo->secno = sno2++; sno++; @@ -1619,17 +1605,15 @@ * Need to generate the updated data buffer */ if ((sinfo->mdata = malloc(sizeof (Elf_Data))) == NULL) { - error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, - prog); + error_message(MALLOC_ERROR, PLAIN_ERROR, (char *)0, + prog); exit(FAILURE); } *(sinfo->mdata) = *(sinfo->data); if ((ngrpdata = sinfo->mdata->d_buf = malloc(sinfo->data->d_size)) == NULL) { - error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, - prog); + error_message(MALLOC_ERROR, PLAIN_ERROR, (char *)0, + prog); exit(FAILURE); } @@ -1637,8 +1621,10 @@ ngrpdata[0] = grpdata[0]; j = 1; for (i = 1; i < num; i++) { - if (sec_table[grpdata[i]].secno != (GElf_Word)DELETED) { - ngrpdata[j++] = sec_table[grpdata[i]].secno; + if (state->sec_table[grpdata[i]].secno != + (GElf_Word)DELETED) { + ngrpdata[j++] = + state->sec_table[grpdata[i]].secno; } } sinfo->mdata->d_size = j * sizeof (Word);
--- a/usr/src/cmd/sgs/mcs/common/mcs.h Mon Oct 01 11:00:58 2007 -0700 +++ b/usr/src/cmd/sgs/mcs/common/mcs.h Mon Oct 01 11:29:33 2007 -0700 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * 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 * or http://www.opensolaris.org/os/licensing. @@ -24,7 +23,7 @@ * All Rights Reserved * * - * Copyright 1999-2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -111,7 +110,7 @@ Elf_Scn *scn; /* Section */ Elf_Data *data; /* Original data */ Elf_Data *mdata; /* Modified data */ - char *name; /* Section name */ + char *name; /* Section name, or NULL if unknown */ char *rel_name; GElf_Shdr shdr; GElf_Word secno; /* The new index */
--- a/usr/src/cmd/sgs/mcs/common/utils.c Mon Oct 01 11:00:58 2007 -0700 +++ b/usr/src/cmd/sgs/mcs/common/utils.c Mon Oct 01 11:29:33 2007 -0700 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * 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 * or http://www.opensolaris.org/os/licensing. @@ -26,7 +25,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -73,9 +72,8 @@ if (GET_ACTION(info->flags) == ACT_DELETE) break; if (shdr.sh_type == SHT_NOBITS) { - error_message(ACT_PRINT_ERROR, - PLAIN_ERROR, (char *)0, - prog, cur_file, SECT_NAME); + error_message(ACT_PRINT_ERROR, PLAIN_ERROR, + (char *)0, prog, cur_file, SECT_NAME); break; } doprint(cur_file, info); @@ -97,10 +95,14 @@ ret = 0; UNSET_CANDIDATE(info->flags); } else { + char *name = info->name; + ret++; + if (name == NULL) + name = gettext("<unknown>"); error_message(ACT_DELETE1_ERROR, - PLAIN_ERROR, (char *)0, - prog, cur_file, info->name); + PLAIN_ERROR, (char *)0, + prog, cur_file, name); } break; } else if (info->rel_loc == IN) { @@ -115,9 +117,9 @@ } else { ret++; error_message(ACT_DELETE2_ERROR, - PLAIN_ERROR, (char *)0, - prog, cur_file, SECT_NAME, - info->rel_name); + PLAIN_ERROR, (char *)0, + prog, cur_file, SECT_NAME, + info->rel_name); } break; } else if (GET_LOC(info->flags) == PRIOR) { @@ -139,14 +141,14 @@ if (shdr.sh_type == SHT_NOBITS) { ret++; error_message(ACT_APPEND1_ERROR, - PLAIN_ERROR, (char *)0, - prog, cur_file, SECT_NAME); + PLAIN_ERROR, (char *)0, + prog, cur_file, SECT_NAME); break; } else if (GET_LOC(info->flags) == IN) { ret++; error_message(ACT_APPEND2_ERROR, - PLAIN_ERROR, (char *)0, - prog, cur_file, SECT_NAME); + PLAIN_ERROR, (char *)0, + prog, cur_file, SECT_NAME); break; } doappend(Action[act_index].a_string, info); @@ -167,14 +169,14 @@ if (shdr.sh_type == SHT_NOBITS) { ret++; error_message(ACT_COMPRESS1_ERROR, - PLAIN_ERROR, (char *)0, - prog, cur_file, SECT_NAME); + PLAIN_ERROR, (char *)0, + prog, cur_file, SECT_NAME); break; } else if (GET_LOC(info->flags) == IN) { ret++; error_message(ACT_COMPRESS2_ERROR, - PLAIN_ERROR, (char *)0, - prog, cur_file, SECT_NAME); + PLAIN_ERROR, (char *)0, + prog, cur_file, SECT_NAME); break; } @@ -200,17 +202,13 @@ info->mdata = data = malloc(sizeof (Elf_Data)); if (data == NULL) { - error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, - prog); + error_message(MALLOC_ERROR, PLAIN_ERROR, (char *)0, prog); exit(1); } *data = *info->data; data->d_buf = calloc(1, data->d_size); if (data->d_buf == NULL) { - error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, - prog); + error_message(MALLOC_ERROR, PLAIN_ERROR, (char *)0, prog); exit(1); } } @@ -288,9 +286,8 @@ */ info->mdata = data = calloc(1, sizeof (Elf_Data)); if (data == NULL) { - error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, - prog); + error_message(MALLOC_ERROR, PLAIN_ERROR, + (char *)0, prog); exit(1); } *data = *info->data; @@ -308,9 +305,8 @@ */ data->d_buf = calloc(1, len + 2); if (data->d_buf == 0) { - error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, - prog); + error_message(MALLOC_ERROR, PLAIN_ERROR, + (char *)0, prog); exit(1); } tp = (char *)data->d_buf; @@ -324,9 +320,8 @@ */ p = malloc(len + 1 + data->d_size); if (p == NULL) { - error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, - prog); + error_message(MALLOC_ERROR, PLAIN_ERROR, + (char *)0, prog); exit(1); } (void) memcpy(p, data->d_buf, data->d_size); @@ -351,9 +346,8 @@ free(data->d_buf); data->d_buf = calloc(1, len + 2); if (data->d_buf == 0) { - error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, - prog); + error_message(MALLOC_ERROR, PLAIN_ERROR, + (char *)0, prog); exit(1); } tp = (char *)data->d_buf; @@ -367,9 +361,8 @@ */ p = malloc(len + 1 + data->d_size); if (p == NULL) { - error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, - prog); + error_message(MALLOC_ERROR, PLAIN_ERROR, + (char *)0, prog); exit(1); } (void) memcpy(p, data->d_buf, data->d_size); @@ -403,9 +396,8 @@ char *p; info->mdata = data = calloc(1, sizeof (Elf_Data)); if (data == NULL) { - error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, - prog); + error_message(MALLOC_ERROR, PLAIN_ERROR, + (char *)0, prog); exit(1); } *data = *info->data; @@ -444,9 +436,7 @@ strings = malloc(str_size); if (hash_key == NULL || hash_str == NULL || strings == NULL) { - error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, - prog); + error_message(MALLOC_ERROR, PLAIN_ERROR, (char *)0, prog); mcs_exit(FAILURE); } @@ -468,8 +458,7 @@ if ((strings = (char *) realloc(strings, str_size)) == NULL) { error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, - prog); + PLAIN_ERROR, (char *)0, prog); mcs_exit(FAILURE); } } @@ -481,8 +470,7 @@ if ((strings = (char *) realloc(strings, str_size)) == NULL) { error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, - prog); + PLAIN_ERROR, (char *)0, prog); mcs_exit(FAILURE); } } @@ -506,13 +494,12 @@ if (hash_num == hash_end) { hash_end *= 2; hash_key = realloc((char *)hash_key, - hash_end * sizeof (int)); + hash_end * sizeof (int)); hash_str = realloc((char *)hash_str, - hash_end * sizeof (size_t)); + hash_end * sizeof (size_t)); if (hash_key == NULL || hash_str == NULL) { error_message(MALLOC_ERROR, - PLAIN_ERROR, (char *)0, - prog); + PLAIN_ERROR, (char *)0, prog); mcs_exit(FAILURE); } }
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README Mon Oct 01 11:00:58 2007 -0700 +++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README Mon Oct 01 11:29:33 2007 -0700 @@ -1262,3 +1262,6 @@ 6234471 need a way to edit ELF objects PSARC/2007/509 elfedit 5035454 mixing -Kpic and -KPIC may cause SIGSEGV with -xarch=v9 +6473571 strip and mcs get confused and corrupt files when passed + non-ELF arguments +6253589 mcs has problems handling multiple SHT_NOTE sections