tools/elf4rom/libs/libelf-0.8.10/lib/x.movscn.c
changeset 34 92d87f2e53c2
equal deleted inserted replaced
33:1af5c1be89f8 34:92d87f2e53c2
       
     1 /*
       
     2 x.movscn.c - implementation of the elfx_movscn(3) function.
       
     3 Copyright (C) 1995 - 2001, 2003 Michael Riepe
       
     4 
       
     5 This library is free software; you can redistribute it and/or
       
     6 modify it under the terms of the GNU Library General Public
       
     7 License as published by the Free Software Foundation; either
       
     8 version 2 of the License, or (at your option) any later version.
       
     9 
       
    10 This library is distributed in the hope that it will be useful,
       
    11 but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    13 Library General Public License for more details.
       
    14 
       
    15 You should have received a copy of the GNU Library General Public
       
    16 License along with this library; if not, write to the Free Software
       
    17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    18 */
       
    19 
       
    20 #include <private.h>
       
    21 
       
    22 #ifndef lint
       
    23 static const char rcsid[] = "@(#) $Id: x.movscn.c,v 1.13 2005/05/21 15:39:27 michael Exp $";
       
    24 #endif /* lint */
       
    25 
       
    26 size_t
       
    27 elfx_movscn(Elf *elf, Elf_Scn *scn, Elf_Scn *after) {
       
    28     Elf_Scn *prev;
       
    29     Elf_Scn *tmp;
       
    30     int off;
       
    31 
       
    32     if (!elf || !scn || !after) {
       
    33 	return SHN_UNDEF;
       
    34     }
       
    35     elf_assert(elf->e_magic == ELF_MAGIC);
       
    36     if (elf->e_kind != ELF_K_ELF) {
       
    37 	seterr(ERROR_NOTELF);
       
    38 	return SHN_UNDEF;
       
    39     }
       
    40     elf_assert(scn->s_magic == SCN_MAGIC);
       
    41     elf_assert(after->s_magic == SCN_MAGIC);
       
    42     if (scn->s_elf != elf || after->s_elf != elf) {
       
    43 	seterr(ERROR_ELFSCNMISMATCH);
       
    44 	return SHN_UNDEF;
       
    45     }
       
    46     elf_assert(elf->e_scn_1);
       
    47     if (scn == elf->e_scn_1) {
       
    48 	seterr(ERROR_NULLSCN);
       
    49 	return SHN_UNDEF;
       
    50     }
       
    51     if (scn == after || scn == after->s_link) {
       
    52 	/* nothing to do */
       
    53 	return scn->s_index;
       
    54     }
       
    55 
       
    56     /*
       
    57      * Find previous section.
       
    58      */
       
    59     prev = NULL;
       
    60     for (tmp = elf->e_scn_1; tmp->s_link; tmp = tmp->s_link) {
       
    61 	if (tmp->s_link == scn) {
       
    62 	    prev = tmp;
       
    63 	    break;
       
    64 	}
       
    65     }
       
    66     elf_assert(prev != NULL);
       
    67 
       
    68     /*
       
    69      * Update section indices
       
    70      */
       
    71     off = 0;
       
    72     for (tmp = elf->e_scn_1; tmp; tmp = tmp->s_link) {
       
    73 	if (off) {
       
    74 	    tmp->s_index += off;
       
    75 	}
       
    76 	if (tmp == after) {
       
    77 	    off++;
       
    78 	}
       
    79 	else if (tmp == scn) {
       
    80 	    off--;
       
    81 	}
       
    82     }
       
    83     elf_assert(off == 0);
       
    84 
       
    85     /*
       
    86      * Move section.
       
    87      */
       
    88     prev->s_link = scn->s_link;
       
    89     scn->s_link = after->s_link;
       
    90     after->s_link = scn;
       
    91     scn->s_index = after->s_index + 1;
       
    92     if (elf->e_scn_n == scn) {
       
    93 	elf->e_scn_n = prev;
       
    94     }
       
    95     else if (elf->e_scn_n == after) {
       
    96 	elf->e_scn_n = scn;
       
    97     }
       
    98 
       
    99 #if ENABLE_DEBUG
       
   100     /*
       
   101      * Check section indices
       
   102      */
       
   103     tmp = elf->e_scn_1;
       
   104     elf_assert(tmp->s_index == 0);
       
   105     while (tmp->s_link) {
       
   106 	elf_assert(tmp->s_link->s_index == tmp->s_index + 1);
       
   107 	tmp = tmp->s_link;
       
   108     }
       
   109 #endif /* ENABLE_DEBUG */
       
   110 
       
   111     return scn->s_index;
       
   112 }