tools/elf4rom/libs/libelf-0.8.10/lib/update.c
author Gareth Stockwell <gareth.stockwell@accenture.com>
Mon, 06 Sep 2010 16:25:43 +0100
changeset 106 3bc1a978be44
parent 34 92d87f2e53c2
permissions -rwxr-xr-x
Fix for Bug 3671 - QEMU GDB stub listens on IPv6-only port on Windows 7 The connection string used by the GDB stub does not specify which version of the Internet Protocol should be used by the port on which it listens. On host platforms with IPv6 support, such as Windows 7, this means that the stub listens on an IPv6-only port. Since the GDB client uses IPv4, this means that the client cannot connect to QEMU.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
34
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
     1
/*
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
     2
 * update.c - implementation of the elf_update(3) function.
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
     3
 * Copyright (C) 1995 - 2006 Michael Riepe
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
     4
 * 
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
     5
 * This library is free software; you can redistribute it and/or
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
     6
 * modify it under the terms of the GNU Library General Public
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
     7
 * License as published by the Free Software Foundation; either
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
     8
 * version 2 of the License, or (at your option) any later version.
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
     9
 * 
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    10
 * This library is distributed in the hope that it will be useful,
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    13
 * Library General Public License for more details.
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    14
 * 
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    15
 * You should have received a copy of the GNU Library General Public
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    16
 * License along with this library; if not, write to the Free Software
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    18
 */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    19
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    20
#include <private.h>
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    21
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    22
#ifndef lint
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    23
static const char rcsid[] = "@(#) $Id: update.c,v 1.32 2006/07/07 22:15:50 michael Exp $";
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    24
#endif /* lint */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    25
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    26
#include <errno.h>
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    27
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    28
#if HAVE_MMAP
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    29
#include <sys/mman.h>
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    30
#endif /* HAVE_MMAP */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    31
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    32
static const unsigned short __encoding = ELFDATA2LSB + (ELFDATA2MSB << 8);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    33
#define native_encoding (*(unsigned char*)&__encoding)
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    34
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    35
#define rewrite(var,val,f)	\
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    36
    do{if((var)!=(val)){(var)=(val);(f)|=ELF_F_DIRTY;}}while(0)
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    37
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    38
#define align(var,val)		\
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    39
    do{if((val)>1){(var)+=(val)-1;(var)-=(var)%(val);}}while(0)
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    40
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    41
#undef max
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    42
#define max(a,b)		((a)>(b)?(a):(b))
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    43
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    44
static off_t
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    45
scn_data_layout(Elf_Scn *scn, unsigned v, unsigned type, size_t *algn, unsigned *flag) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    46
    Elf *elf = scn->s_elf;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    47
    Elf_Data *data;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    48
    int layout = (elf->e_elf_flags & ELF_F_LAYOUT) == 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    49
    size_t scn_align = 1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    50
    size_t len = 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    51
    Scn_Data *sd;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    52
    size_t fsize;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    53
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    54
    if (!(sd = scn->s_data_1)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    55
	/* no data in section */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    56
	*algn = scn_align;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    57
	return (off_t)len;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    58
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    59
    /* load data from file, if any */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    60
    if (!(data = elf_getdata(scn, NULL))) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    61
	return (off_t)-1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    62
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    63
    elf_assert(data == &sd->sd_data);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    64
    for (; sd; sd = sd->sd_link) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    65
	elf_assert(sd->sd_magic == DATA_MAGIC);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    66
	elf_assert(sd->sd_scn == scn);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    67
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    68
	if (!valid_version(sd->sd_data.d_version)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    69
	    return (off_t)-1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    70
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    71
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    72
	fsize = sd->sd_data.d_size;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    73
	if (fsize && type != SHT_NOBITS && valid_type(sd->sd_data.d_type)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    74
	    if (elf->e_class == ELFCLASS32) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    75
		fsize = _elf32_xltsize(&sd->sd_data, v, ELFDATA2LSB, 1);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    76
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    77
#if __LIBELF64
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    78
	    else if (elf->e_class == ELFCLASS64) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    79
		fsize = _elf64_xltsize(&sd->sd_data, v, ELFDATA2LSB, 1);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    80
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    81
#endif /* __LIBELF64 */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    82
	    else {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    83
		elf_assert(valid_class(elf->e_class));
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    84
		seterr(ERROR_UNIMPLEMENTED);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    85
		return (off_t)-1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    86
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    87
	    if (fsize == (size_t)-1) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    88
		return (off_t)-1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    89
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    90
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    91
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    92
	if (layout) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    93
	    align(len, sd->sd_data.d_align);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    94
	    scn_align = max(scn_align, sd->sd_data.d_align);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    95
	    rewrite(sd->sd_data.d_off, (off_t)len, sd->sd_data_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    96
	    len += fsize;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    97
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    98
	else {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    99
	    len = max(len, sd->sd_data.d_off + fsize);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   100
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   101
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   102
	*flag |= sd->sd_data_flags;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   103
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   104
    *algn = scn_align;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   105
    return (off_t)len;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   106
}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   107
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   108
static size_t
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   109
scn_entsize(const Elf *elf, unsigned version, unsigned stype) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   110
    Elf_Type type;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   111
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   112
    switch ((type = _elf_scn_type(stype))) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   113
	case ELF_T_BYTE:
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   114
	    return 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   115
	case ELF_T_VDEF:
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   116
	case ELF_T_VNEED:
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   117
	    return 0;	/* What else can I do?  Thank you, Sun! */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   118
	default:
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   119
	    return _fsize(elf->e_class, version, type);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   120
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   121
}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   122
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   123
static off_t
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   124
_elf32_layout(Elf *elf, unsigned *flag) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   125
    int layout = (elf->e_elf_flags & ELF_F_LAYOUT) == 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   126
    Elf32_Ehdr *ehdr = (Elf32_Ehdr*)elf->e_ehdr;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   127
    size_t off = 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   128
    unsigned version;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   129
    unsigned encoding;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   130
    size_t align_addr;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   131
    size_t entsize;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   132
    unsigned phnum;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   133
    unsigned shnum;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   134
    Elf_Scn *scn;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   135
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   136
    *flag = elf->e_elf_flags | elf->e_phdr_flags;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   137
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   138
    if ((version = ehdr->e_version) == EV_NONE) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   139
	version = EV_CURRENT;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   140
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   141
    if (!valid_version(version)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   142
	seterr(ERROR_UNKNOWN_VERSION);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   143
	return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   144
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   145
    if ((encoding = ehdr->e_ident[EI_DATA]) == ELFDATANONE) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   146
	encoding = native_encoding;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   147
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   148
    if (!valid_encoding(encoding)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   149
	seterr(ERROR_UNKNOWN_ENCODING);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   150
	return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   151
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   152
    entsize = _fsize(ELFCLASS32, version, ELF_T_EHDR);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   153
    elf_assert(entsize);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   154
    rewrite(ehdr->e_ehsize, entsize, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   155
    off = entsize;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   156
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   157
    align_addr = _fsize(ELFCLASS32, version, ELF_T_ADDR);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   158
    elf_assert(align_addr);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   159
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   160
    if ((phnum = elf->e_phnum)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   161
	entsize = _fsize(ELFCLASS32, version, ELF_T_PHDR);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   162
	elf_assert(entsize);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   163
	if (layout) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   164
	    align(off, align_addr);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   165
	    rewrite(ehdr->e_phoff, off, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   166
	    off += phnum * entsize;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   167
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   168
	else {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   169
	    off = max(off, ehdr->e_phoff + phnum * entsize);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   170
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   171
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   172
    else {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   173
	entsize = 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   174
	if (layout) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   175
	    rewrite(ehdr->e_phoff, 0, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   176
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   177
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   178
    if (phnum >= PN_XNUM) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   179
	Elf_Scn *scn = elf->e_scn_1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   180
	Elf32_Shdr *shdr = &scn->s_shdr32;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   181
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   182
	elf_assert(scn);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   183
	elf_assert(scn->s_index == 0);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   184
	rewrite(shdr->sh_info, phnum, scn->s_shdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   185
	*flag |= scn->s_shdr_flags;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   186
	phnum = PN_XNUM;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   187
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   188
    rewrite(ehdr->e_phnum, phnum, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   189
    rewrite(ehdr->e_phentsize, entsize, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   190
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   191
    for (scn = elf->e_scn_1, shnum = 0; scn; scn = scn->s_link, ++shnum) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   192
	Elf32_Shdr *shdr = &scn->s_shdr32;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   193
	size_t scn_align = 1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   194
	off_t len;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   195
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   196
	elf_assert(scn->s_index == shnum);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   197
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   198
	*flag |= scn->s_scn_flags;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   199
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   200
	if (scn->s_index == SHN_UNDEF) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   201
	    rewrite(shdr->sh_entsize, 0, scn->s_shdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   202
	    if (layout) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   203
		rewrite(shdr->sh_offset, 0, scn->s_shdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   204
		rewrite(shdr->sh_size, 0, scn->s_shdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   205
		rewrite(shdr->sh_addralign, 0, scn->s_shdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   206
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   207
	    *flag |= scn->s_shdr_flags;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   208
	    continue;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   209
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   210
	if (shdr->sh_type == SHT_NULL) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   211
	    *flag |= scn->s_shdr_flags;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   212
	    continue;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   213
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   214
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   215
	len = scn_data_layout(scn, version, shdr->sh_type, &scn_align, flag);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   216
	if (len == -1) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   217
	    return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   218
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   219
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   220
	/*
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   221
	 * Never override the program's choice.
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   222
	 */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   223
	if (shdr->sh_entsize == 0) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   224
	    entsize = scn_entsize(elf, version, shdr->sh_type);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   225
	    if (entsize > 1) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   226
		rewrite(shdr->sh_entsize, entsize, scn->s_shdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   227
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   228
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   229
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   230
	if (layout) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   231
	    align(off, scn_align);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   232
	    rewrite(shdr->sh_offset, off, scn->s_shdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   233
	    rewrite(shdr->sh_size, (size_t)len, scn->s_shdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   234
	    rewrite(shdr->sh_addralign, scn_align, scn->s_shdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   235
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   236
	    if (shdr->sh_type != SHT_NOBITS) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   237
		off += (size_t)len;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   238
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   239
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   240
	else if ((size_t)len > shdr->sh_size) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   241
	    seterr(ERROR_SCN2SMALL);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   242
	    return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   243
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   244
	else {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   245
	    Elf_Scn *scn2;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   246
	    size_t end1, end2;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   247
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   248
	    end1 = shdr->sh_offset;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   249
	    if (shdr->sh_type != SHT_NOBITS) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   250
		end1 += shdr->sh_size;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   251
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   252
	    if (shdr->sh_offset < off) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   253
		/*
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   254
		 * check for overlapping sections
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   255
		 */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   256
		for (scn2 = elf->e_scn_1; scn2; scn2 = scn2->s_link) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   257
		    if (scn2 == scn) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   258
			break;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   259
		    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   260
		    end2 = scn2->s_shdr32.sh_offset;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   261
		    if (scn2->s_shdr32.sh_type != SHT_NOBITS) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   262
			end2 += scn2->s_shdr32.sh_size;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   263
		    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   264
		    if (end1 > scn2->s_shdr32.sh_offset
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   265
		     && end2 > shdr->sh_offset) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   266
			seterr(ERROR_SCN_OVERLAP);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   267
			return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   268
		    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   269
		}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   270
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   271
	    if (off < end1) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   272
		off = end1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   273
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   274
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   275
	*flag |= scn->s_shdr_flags;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   276
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   277
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   278
    if (shnum) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   279
	entsize = _fsize(ELFCLASS32, version, ELF_T_SHDR);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   280
	elf_assert(entsize);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   281
	if (layout) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   282
	    align(off, align_addr);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   283
	    rewrite(ehdr->e_shoff, off, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   284
	    off += shnum * entsize;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   285
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   286
	else {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   287
	    off = max(off, ehdr->e_shoff + shnum * entsize);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   288
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   289
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   290
    else {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   291
	entsize = 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   292
	if (layout) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   293
	    rewrite(ehdr->e_shoff, 0, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   294
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   295
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   296
    if (shnum >= SHN_LORESERVE) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   297
	Elf_Scn *scn = elf->e_scn_1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   298
	Elf32_Shdr *shdr = &scn->s_shdr32;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   299
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   300
	elf_assert(scn->s_index == 0);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   301
	rewrite(shdr->sh_size, shnum, scn->s_shdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   302
	*flag |= scn->s_shdr_flags;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   303
	shnum = 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   304
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   305
    rewrite(ehdr->e_shnum, shnum, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   306
    rewrite(ehdr->e_shentsize, entsize, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   307
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   308
    rewrite(ehdr->e_ident[EI_MAG0], ELFMAG0, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   309
    rewrite(ehdr->e_ident[EI_MAG1], ELFMAG1, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   310
    rewrite(ehdr->e_ident[EI_MAG2], ELFMAG2, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   311
    rewrite(ehdr->e_ident[EI_MAG3], ELFMAG3, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   312
    rewrite(ehdr->e_ident[EI_CLASS], ELFCLASS32, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   313
    rewrite(ehdr->e_ident[EI_DATA], encoding, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   314
    rewrite(ehdr->e_ident[EI_VERSION], version, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   315
    rewrite(ehdr->e_version, version, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   316
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   317
    *flag |= elf->e_ehdr_flags;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   318
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   319
    return off;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   320
}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   321
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   322
#if __LIBELF64
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   323
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   324
static off_t
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   325
_elf64_layout(Elf *elf, unsigned *flag) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   326
    int layout = (elf->e_elf_flags & ELF_F_LAYOUT) == 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   327
    Elf64_Ehdr *ehdr = (Elf64_Ehdr*)elf->e_ehdr;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   328
    size_t off = 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   329
    unsigned version;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   330
    unsigned encoding;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   331
    size_t align_addr;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   332
    size_t entsize;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   333
    unsigned phnum;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   334
    unsigned shnum;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   335
    Elf_Scn *scn;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   336
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   337
    *flag = elf->e_elf_flags | elf->e_phdr_flags;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   338
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   339
    if ((version = ehdr->e_version) == EV_NONE) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   340
	version = EV_CURRENT;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   341
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   342
    if (!valid_version(version)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   343
	seterr(ERROR_UNKNOWN_VERSION);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   344
	return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   345
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   346
    if ((encoding = ehdr->e_ident[EI_DATA]) == ELFDATANONE) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   347
	encoding = native_encoding;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   348
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   349
    if (!valid_encoding(encoding)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   350
	seterr(ERROR_UNKNOWN_ENCODING);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   351
	return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   352
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   353
    entsize = _fsize(ELFCLASS64, version, ELF_T_EHDR);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   354
    elf_assert(entsize);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   355
    rewrite(ehdr->e_ehsize, entsize, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   356
    off = entsize;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   357
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   358
    align_addr = _fsize(ELFCLASS64, version, ELF_T_ADDR);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   359
    elf_assert(align_addr);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   360
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   361
    if ((phnum = elf->e_phnum)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   362
	entsize = _fsize(ELFCLASS64, version, ELF_T_PHDR);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   363
	elf_assert(entsize);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   364
	if (layout) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   365
	    align(off, align_addr);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   366
	    rewrite(ehdr->e_phoff, off, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   367
	    off += phnum * entsize;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   368
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   369
	else {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   370
	    off = max(off, ehdr->e_phoff + phnum * entsize);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   371
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   372
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   373
    else {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   374
	entsize = 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   375
	if (layout) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   376
	    rewrite(ehdr->e_phoff, 0, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   377
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   378
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   379
    if (phnum >= PN_XNUM) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   380
	Elf_Scn *scn = elf->e_scn_1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   381
	Elf32_Shdr *shdr = &scn->s_shdr32;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   382
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   383
	/* modify first section header, too! */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   384
	elf_assert(scn);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   385
	elf_assert(scn->s_index == 0);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   386
	rewrite(shdr->sh_info, phnum, scn->s_shdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   387
	*flag |= scn->s_shdr_flags;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   388
	phnum = PN_XNUM;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   389
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   390
    rewrite(ehdr->e_phnum, phnum, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   391
    rewrite(ehdr->e_phentsize, entsize, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   392
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   393
    for (scn = elf->e_scn_1, shnum = 0; scn; scn = scn->s_link, ++shnum) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   394
	Elf64_Shdr *shdr = &scn->s_shdr64;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   395
	size_t scn_align = 1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   396
	off_t len;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   397
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   398
	elf_assert(scn->s_index == shnum);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   399
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   400
	*flag |= scn->s_scn_flags;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   401
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   402
	if (scn->s_index == SHN_UNDEF) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   403
	    rewrite(shdr->sh_entsize, 0, scn->s_shdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   404
	    if (layout) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   405
		rewrite(shdr->sh_offset, 0, scn->s_shdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   406
		rewrite(shdr->sh_size, 0, scn->s_shdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   407
		rewrite(shdr->sh_addralign, 0, scn->s_shdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   408
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   409
	    *flag |= scn->s_shdr_flags;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   410
	    continue;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   411
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   412
	if (shdr->sh_type == SHT_NULL) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   413
	    *flag |= scn->s_shdr_flags;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   414
	    continue;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   415
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   416
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   417
	len = scn_data_layout(scn, version, shdr->sh_type, &scn_align, flag);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   418
	if (len == -1) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   419
	    return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   420
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   421
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   422
	/*
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   423
	 * Never override the program's choice.
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   424
	 */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   425
	if (shdr->sh_entsize == 0) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   426
	    entsize = scn_entsize(elf, version, shdr->sh_type);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   427
	    if (entsize > 1) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   428
		rewrite(shdr->sh_entsize, entsize, scn->s_shdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   429
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   430
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   431
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   432
	if (layout) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   433
	    align(off, scn_align);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   434
	    rewrite(shdr->sh_offset, off, scn->s_shdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   435
	    rewrite(shdr->sh_size, (size_t)len, scn->s_shdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   436
	    rewrite(shdr->sh_addralign, scn_align, scn->s_shdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   437
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   438
	    if (shdr->sh_type != SHT_NOBITS) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   439
		off += (size_t)len;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   440
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   441
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   442
	else if ((size_t)len > shdr->sh_size) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   443
	    seterr(ERROR_SCN2SMALL);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   444
	    return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   445
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   446
	else {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   447
	    Elf_Scn *scn2;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   448
	    size_t end1, end2;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   449
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   450
	    end1 = shdr->sh_offset;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   451
	    if (shdr->sh_type != SHT_NOBITS) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   452
		end1 += shdr->sh_size;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   453
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   454
	    if (shdr->sh_offset < off) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   455
		/*
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   456
		 * check for overlapping sections
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   457
		 */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   458
		for (scn2 = elf->e_scn_1; scn2; scn2 = scn2->s_link) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   459
		    if (scn2 == scn) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   460
			break;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   461
		    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   462
		    end2 = scn2->s_shdr64.sh_offset;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   463
		    if (scn2->s_shdr64.sh_type != SHT_NOBITS) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   464
			end2 += scn2->s_shdr64.sh_size;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   465
		    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   466
		    if (end1 > scn2->s_shdr64.sh_offset
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   467
		     && end2 > shdr->sh_offset) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   468
			seterr(ERROR_SCN_OVERLAP);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   469
			return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   470
		    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   471
		}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   472
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   473
	    if (off < end1) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   474
		off = end1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   475
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   476
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   477
	*flag |= scn->s_shdr_flags;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   478
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   479
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   480
    if (shnum) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   481
	entsize = _fsize(ELFCLASS64, version, ELF_T_SHDR);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   482
	elf_assert(entsize);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   483
	if (layout) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   484
	    align(off, align_addr);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   485
	    rewrite(ehdr->e_shoff, off, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   486
	    off += shnum * entsize;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   487
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   488
	else {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   489
	    off = max(off, ehdr->e_shoff + shnum * entsize);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   490
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   491
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   492
    else {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   493
	entsize = 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   494
	if (layout) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   495
	    rewrite(ehdr->e_shoff, 0, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   496
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   497
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   498
    if (shnum >= SHN_LORESERVE) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   499
	Elf_Scn *scn = elf->e_scn_1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   500
	Elf64_Shdr *shdr = &scn->s_shdr64;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   501
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   502
	elf_assert(scn->s_index == 0);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   503
	rewrite(shdr->sh_size, shnum, scn->s_shdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   504
	*flag |= scn->s_shdr_flags;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   505
	shnum = 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   506
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   507
    rewrite(ehdr->e_shnum, shnum, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   508
    rewrite(ehdr->e_shentsize, entsize, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   509
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   510
    rewrite(ehdr->e_ident[EI_MAG0], ELFMAG0, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   511
    rewrite(ehdr->e_ident[EI_MAG1], ELFMAG1, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   512
    rewrite(ehdr->e_ident[EI_MAG2], ELFMAG2, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   513
    rewrite(ehdr->e_ident[EI_MAG3], ELFMAG3, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   514
    rewrite(ehdr->e_ident[EI_CLASS], ELFCLASS64, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   515
    rewrite(ehdr->e_ident[EI_DATA], encoding, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   516
    rewrite(ehdr->e_ident[EI_VERSION], version, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   517
    rewrite(ehdr->e_version, version, elf->e_ehdr_flags);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   518
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   519
    *flag |= elf->e_ehdr_flags;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   520
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   521
    return off;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   522
}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   523
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   524
#endif /* __LIBELF64 */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   525
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   526
#define ptrinside(p,a,l)	((p)>=(a)&&(p)<(a)+(l))
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   527
#define newptr(p,o,n)		((p)=((p)-(o))+(n))
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   528
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   529
static int
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   530
_elf_update_pointers(Elf *elf, char *outbuf, size_t len) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   531
    Elf_Scn *scn;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   532
    Scn_Data *sd;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   533
    char *data, *rawdata;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   534
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   535
    elf_assert(elf);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   536
    elf_assert(elf->e_data);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   537
    elf_assert(!elf->e_parent);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   538
    elf_assert(!elf->e_unmap_data);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   539
    elf_assert(elf->e_kind == ELF_K_ELF);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   540
    elf_assert(len >= EI_NIDENT);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   541
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   542
    /* resize memory images */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   543
    if (len <= elf->e_dsize) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   544
	/* don't shorten the memory image */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   545
	data = elf->e_data;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   546
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   547
    else if ((data = (char*)realloc(elf->e_data, len))) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   548
	elf->e_dsize = len;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   549
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   550
    else {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   551
	seterr(ERROR_IO_2BIG);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   552
	return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   553
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   554
    if (elf->e_rawdata == elf->e_data) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   555
	/* update frozen raw image */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   556
	memcpy(data, outbuf, len);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   557
	elf->e_data = elf->e_rawdata = data;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   558
	/* cooked data is stored outside the raw image */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   559
	return 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   560
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   561
    if (elf->e_rawdata) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   562
	/* update raw image */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   563
	if (!(rawdata = (char*)realloc(elf->e_rawdata, len))) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   564
	    seterr(ERROR_IO_2BIG);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   565
	    return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   566
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   567
	memcpy(rawdata, outbuf, len);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   568
	elf->e_rawdata = rawdata;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   569
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   570
    if (data == elf->e_data) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   571
	/* nothing more to do */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   572
	return 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   573
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   574
    /* adjust internal pointers */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   575
    for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   576
	elf_assert(scn->s_magic == SCN_MAGIC);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   577
	elf_assert(scn->s_elf == elf);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   578
	if ((sd = scn->s_data_1)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   579
	    elf_assert(sd->sd_magic == DATA_MAGIC);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   580
	    elf_assert(sd->sd_scn == scn);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   581
	    if (sd->sd_memdata && !sd->sd_free_data) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   582
		elf_assert(ptrinside(sd->sd_memdata, elf->e_data, elf->e_dsize));
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   583
		if (sd->sd_data.d_buf == sd->sd_memdata) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   584
		    newptr(sd->sd_memdata, elf->e_data, data);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   585
		    sd->sd_data.d_buf = sd->sd_memdata;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   586
		}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   587
		else {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   588
		    newptr(sd->sd_memdata, elf->e_data, data);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   589
		}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   590
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   591
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   592
	if ((sd = scn->s_rawdata)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   593
	    elf_assert(sd->sd_magic == DATA_MAGIC);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   594
	    elf_assert(sd->sd_scn == scn);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   595
	    if (sd->sd_memdata && sd->sd_free_data) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   596
		size_t off, len;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   597
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   598
		if (elf->e_class == ELFCLASS32) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   599
		    off = scn->s_shdr32.sh_offset;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   600
		    len = scn->s_shdr32.sh_size;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   601
		}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   602
#if __LIBELF64
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   603
		else if (elf->e_class == ELFCLASS64) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   604
		    off = scn->s_shdr64.sh_offset;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   605
		    len = scn->s_shdr64.sh_size;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   606
		}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   607
#endif /* __LIBELF64 */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   608
		else {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   609
		    seterr(ERROR_UNIMPLEMENTED);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   610
		    return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   611
		}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   612
		if (!(rawdata = (char*)realloc(sd->sd_memdata, len))) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   613
		    seterr(ERROR_IO_2BIG);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   614
		    return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   615
		}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   616
		memcpy(rawdata, outbuf + off, len);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   617
		if (sd->sd_data.d_buf == sd->sd_memdata) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   618
		    sd->sd_data.d_buf = rawdata;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   619
		}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   620
		sd->sd_memdata = rawdata;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   621
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   622
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   623
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   624
    elf->e_data = data;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   625
    return 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   626
}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   627
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   628
#undef ptrinside
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   629
#undef newptr
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   630
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   631
static off_t
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   632
_elf32_write(Elf *elf, char *outbuf, size_t len) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   633
    Elf32_Ehdr *ehdr;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   634
    Elf32_Shdr *shdr;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   635
    Elf_Scn *scn;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   636
    Scn_Data *sd;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   637
    Elf_Data src;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   638
    Elf_Data dst;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   639
    unsigned encode;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   640
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   641
    elf_assert(len);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   642
    elf_assert(elf->e_ehdr);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   643
    ehdr = (Elf32_Ehdr*)elf->e_ehdr;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   644
    encode = ehdr->e_ident[EI_DATA];
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   645
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   646
    src.d_buf = ehdr;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   647
    src.d_type = ELF_T_EHDR;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   648
    src.d_size = _msize(ELFCLASS32, _elf_version, ELF_T_EHDR);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   649
    src.d_version = _elf_version;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   650
    dst.d_buf = outbuf;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   651
    dst.d_size = ehdr->e_ehsize;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   652
    dst.d_version = ehdr->e_version;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   653
    if (!elf32_xlatetof(&dst, &src, encode)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   654
	return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   655
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   656
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   657
    if (elf->e_phnum) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   658
	src.d_buf = elf->e_phdr;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   659
	src.d_type = ELF_T_PHDR;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   660
	src.d_size = elf->e_phnum * _msize(ELFCLASS32, _elf_version, ELF_T_PHDR);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   661
	src.d_version = _elf_version;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   662
	dst.d_buf = outbuf + ehdr->e_phoff;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   663
	dst.d_size = elf->e_phnum * ehdr->e_phentsize;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   664
	dst.d_version = ehdr->e_version;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   665
	if (!elf32_xlatetof(&dst, &src, encode)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   666
	    return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   667
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   668
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   669
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   670
    for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   671
	elf_assert(scn->s_magic == SCN_MAGIC);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   672
	elf_assert(scn->s_elf == elf);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   673
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   674
	src.d_buf = &scn->s_uhdr;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   675
	src.d_type = ELF_T_SHDR;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   676
	src.d_size = _msize(ELFCLASS32, EV_CURRENT, ELF_T_SHDR);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   677
	src.d_version = EV_CURRENT;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   678
	dst.d_buf = outbuf + ehdr->e_shoff + scn->s_index * ehdr->e_shentsize;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   679
	dst.d_size = ehdr->e_shentsize;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   680
	dst.d_version = ehdr->e_version;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   681
	if (!elf32_xlatetof(&dst, &src, encode)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   682
	    return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   683
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   684
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   685
	if (scn->s_index == SHN_UNDEF) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   686
	    continue;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   687
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   688
	shdr = &scn->s_shdr32;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   689
	if (shdr->sh_type == SHT_NULL || shdr->sh_type == SHT_NOBITS) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   690
	    continue;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   691
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   692
	/* XXX: this is probably no longer necessary */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   693
	if (scn->s_data_1 && !elf_getdata(scn, NULL)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   694
	    return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   695
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   696
	for (sd = scn->s_data_1; sd; sd = sd->sd_link) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   697
	    elf_assert(sd->sd_magic == DATA_MAGIC);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   698
	    elf_assert(sd->sd_scn == scn);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   699
	    src = sd->sd_data;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   700
	    if (!src.d_size) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   701
		continue;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   702
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   703
	    if (!src.d_buf) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   704
		seterr(ERROR_NULLBUF);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   705
		return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   706
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   707
	    dst.d_buf = outbuf + shdr->sh_offset + src.d_off;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   708
	    dst.d_size = src.d_size;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   709
	    dst.d_version = ehdr->e_version;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   710
	    if (valid_type(src.d_type)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   711
		size_t tmp;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   712
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   713
		tmp = _elf32_xltsize(&src, dst.d_version, ELFDATA2LSB, 1);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   714
		if (tmp == (size_t)-1) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   715
		    return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   716
		}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   717
		dst.d_size = tmp;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   718
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   719
	    else {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   720
		src.d_type = ELF_T_BYTE;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   721
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   722
	    if (!elf32_xlatetof(&dst, &src, encode)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   723
		return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   724
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   725
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   726
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   727
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   728
    /* cleanup */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   729
    if (elf->e_readable && _elf_update_pointers(elf, outbuf, len)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   730
	return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   731
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   732
    /* NOTE: ehdr is no longer valid! */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   733
    ehdr = (Elf32_Ehdr*)elf->e_ehdr; elf_assert(ehdr);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   734
    elf->e_encoding = ehdr->e_ident[EI_DATA];
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   735
    elf->e_version = ehdr->e_ident[EI_VERSION];
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   736
    elf->e_elf_flags &= ~ELF_F_DIRTY;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   737
    elf->e_ehdr_flags &= ~ELF_F_DIRTY;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   738
    elf->e_phdr_flags &= ~ELF_F_DIRTY;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   739
    for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   740
	scn->s_scn_flags &= ~ELF_F_DIRTY;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   741
	scn->s_shdr_flags &= ~ELF_F_DIRTY;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   742
	for (sd = scn->s_data_1; sd; sd = sd->sd_link) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   743
	    sd->sd_data_flags &= ~ELF_F_DIRTY;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   744
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   745
	if (elf->e_readable) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   746
	    shdr = &scn->s_shdr32;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   747
	    scn->s_type = shdr->sh_type;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   748
	    scn->s_size = shdr->sh_size;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   749
	    scn->s_offset = shdr->sh_offset;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   750
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   751
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   752
    elf->e_size = len;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   753
    return len;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   754
}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   755
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   756
#if __LIBELF64
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   757
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   758
static off_t
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   759
_elf64_write(Elf *elf, char *outbuf, size_t len) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   760
    Elf64_Ehdr *ehdr;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   761
    Elf64_Shdr *shdr;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   762
    Elf_Scn *scn;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   763
    Scn_Data *sd;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   764
    Elf_Data src;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   765
    Elf_Data dst;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   766
    unsigned encode;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   767
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   768
    elf_assert(len);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   769
    elf_assert(elf->e_ehdr);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   770
    ehdr = (Elf64_Ehdr*)elf->e_ehdr;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   771
    encode = ehdr->e_ident[EI_DATA];
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   772
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   773
    src.d_buf = ehdr;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   774
    src.d_type = ELF_T_EHDR;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   775
    src.d_size = _msize(ELFCLASS64, _elf_version, ELF_T_EHDR);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   776
    src.d_version = _elf_version;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   777
    dst.d_buf = outbuf;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   778
    dst.d_size = ehdr->e_ehsize;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   779
    dst.d_version = ehdr->e_version;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   780
    if (!elf64_xlatetof(&dst, &src, encode)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   781
	return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   782
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   783
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   784
    if (elf->e_phnum) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   785
	src.d_buf = elf->e_phdr;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   786
	src.d_type = ELF_T_PHDR;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   787
	src.d_size = elf->e_phnum * _msize(ELFCLASS64, _elf_version, ELF_T_PHDR);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   788
	src.d_version = _elf_version;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   789
	dst.d_buf = outbuf + ehdr->e_phoff;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   790
	dst.d_size = elf->e_phnum * ehdr->e_phentsize;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   791
	dst.d_version = ehdr->e_version;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   792
	if (!elf64_xlatetof(&dst, &src, encode)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   793
	    return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   794
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   795
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   796
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   797
    for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   798
	elf_assert(scn->s_magic == SCN_MAGIC);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   799
	elf_assert(scn->s_elf == elf);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   800
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   801
	src.d_buf = &scn->s_uhdr;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   802
	src.d_type = ELF_T_SHDR;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   803
	src.d_size = _msize(ELFCLASS64, EV_CURRENT, ELF_T_SHDR);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   804
	src.d_version = EV_CURRENT;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   805
	dst.d_buf = outbuf + ehdr->e_shoff + scn->s_index * ehdr->e_shentsize;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   806
	dst.d_size = ehdr->e_shentsize;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   807
	dst.d_version = ehdr->e_version;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   808
	if (!elf64_xlatetof(&dst, &src, encode)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   809
	    return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   810
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   811
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   812
	if (scn->s_index == SHN_UNDEF) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   813
	    continue;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   814
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   815
	shdr = &scn->s_shdr64;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   816
	if (shdr->sh_type == SHT_NULL || shdr->sh_type == SHT_NOBITS) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   817
	    continue;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   818
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   819
	/* XXX: this is probably no longer necessary */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   820
	if (scn->s_data_1 && !elf_getdata(scn, NULL)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   821
	    return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   822
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   823
	for (sd = scn->s_data_1; sd; sd = sd->sd_link) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   824
	    elf_assert(sd->sd_magic == DATA_MAGIC);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   825
	    elf_assert(sd->sd_scn == scn);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   826
	    src = sd->sd_data;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   827
	    if (!src.d_size) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   828
		continue;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   829
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   830
	    if (!src.d_buf) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   831
		seterr(ERROR_NULLBUF);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   832
		return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   833
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   834
	    dst.d_buf = outbuf + shdr->sh_offset + src.d_off;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   835
	    dst.d_size = src.d_size;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   836
	    dst.d_version = ehdr->e_version;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   837
	    if (valid_type(src.d_type)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   838
		size_t tmp;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   839
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   840
		tmp = _elf64_xltsize(&src, dst.d_version, ELFDATA2LSB, 1);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   841
		if (tmp == (size_t)-1) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   842
		    return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   843
		}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   844
		dst.d_size = tmp;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   845
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   846
	    else {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   847
		src.d_type = ELF_T_BYTE;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   848
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   849
	    if (!elf64_xlatetof(&dst, &src, encode)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   850
		return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   851
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   852
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   853
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   854
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   855
    /* cleanup */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   856
    if (elf->e_readable && _elf_update_pointers(elf, outbuf, len)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   857
	return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   858
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   859
    /* NOTE: ehdr is no longer valid! */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   860
    ehdr = (Elf64_Ehdr*)elf->e_ehdr; elf_assert(ehdr);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   861
    elf->e_encoding = ehdr->e_ident[EI_DATA];
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   862
    elf->e_version = ehdr->e_ident[EI_VERSION];
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   863
    elf->e_elf_flags &= ~ELF_F_DIRTY;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   864
    elf->e_ehdr_flags &= ~ELF_F_DIRTY;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   865
    elf->e_phdr_flags &= ~ELF_F_DIRTY;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   866
    for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   867
	scn->s_scn_flags &= ~ELF_F_DIRTY;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   868
	scn->s_shdr_flags &= ~ELF_F_DIRTY;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   869
	for (sd = scn->s_data_1; sd; sd = sd->sd_link) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   870
	    sd->sd_data_flags &= ~ELF_F_DIRTY;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   871
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   872
	if (elf->e_readable) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   873
	    shdr = &scn->s_shdr64;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   874
	    scn->s_type = shdr->sh_type;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   875
	    scn->s_size = shdr->sh_size;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   876
	    scn->s_offset = shdr->sh_offset;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   877
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   878
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   879
    elf->e_size = len;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   880
    return len;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   881
}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   882
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   883
#endif /* __LIBELF64 */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   884
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   885
static int
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   886
xwrite(int fd, char *buffer, size_t len) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   887
    size_t done = 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   888
    size_t n;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   889
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   890
    while (done < len) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   891
	n = write(fd, buffer + done, len - done);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   892
	if (n == 0) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   893
	    /* file system full */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   894
	    return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   895
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   896
	else if (n != (size_t)-1) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   897
	    /* some bytes written, continue */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   898
	    done += n;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   899
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   900
	else if (errno != EAGAIN && errno != EINTR) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   901
	    /* real error */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   902
	    return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   903
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   904
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   905
    return 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   906
}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   907
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   908
static off_t
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   909
_elf_output(Elf *elf, int fd, size_t len, off_t (*_elf_write)(Elf*, char*, size_t)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   910
    char *buf;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   911
    off_t err;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   912
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   913
    elf_assert(len);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   914
#if HAVE_FTRUNCATE
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   915
    ftruncate(fd, 0);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   916
#endif /* HAVE_FTRUNCATE */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   917
#if HAVE_MMAP
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   918
    /*
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   919
     * Make sure the file is (at least) len bytes long
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   920
     */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   921
#if HAVE_FTRUNCATE
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   922
    lseek(fd, (off_t)len, SEEK_SET);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   923
    if (ftruncate(fd, len)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   924
#else /* HAVE_FTRUNCATE */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   925
    {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   926
#endif /* HAVE_FTRUNCATE */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   927
	if (lseek(fd, (off_t)len - 1, SEEK_SET) != (off_t)len - 1) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   928
	    seterr(ERROR_IO_SEEK);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   929
	    return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   930
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   931
	if (xwrite(fd, "", 1)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   932
	    seterr(ERROR_IO_WRITE);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   933
	    return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   934
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   935
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   936
    buf = (void*)mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   937
    if (buf != (char*)-1) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   938
	if ((char)_elf_fill && !(elf->e_elf_flags & ELF_F_LAYOUT)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   939
	    memset(buf, _elf_fill, len);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   940
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   941
	err = _elf_write(elf, buf, len);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   942
	munmap(buf, len);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   943
	return err;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   944
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   945
#endif /* HAVE_MMAP */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   946
    if (!(buf = (char*)malloc(len))) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   947
	seterr(ERROR_MEM_OUTBUF);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   948
	return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   949
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   950
    memset(buf, _elf_fill, len);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   951
    err = _elf_write(elf, buf, len);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   952
    if (err != -1 && (size_t)err == len) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   953
	if (lseek(fd, (off_t)0, SEEK_SET)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   954
	    seterr(ERROR_IO_SEEK);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   955
	    err = -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   956
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   957
	else if (xwrite(fd, buf, len)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   958
	    seterr(ERROR_IO_WRITE);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   959
	    err = -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   960
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   961
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   962
    free(buf);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   963
    return err;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   964
}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   965
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   966
off_t
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   967
elf_update(Elf *elf, Elf_Cmd cmd) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   968
    unsigned flag;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   969
    off_t len;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   970
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   971
    if (!elf) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   972
	return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   973
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   974
    elf_assert(elf->e_magic == ELF_MAGIC);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   975
    if (cmd == ELF_C_WRITE) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   976
	if (!elf->e_writable) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   977
	    seterr(ERROR_RDONLY);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   978
	    return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   979
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   980
	if (elf->e_disabled) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   981
	    seterr(ERROR_FDDISABLED);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   982
	    return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   983
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   984
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   985
    else if (cmd != ELF_C_NULL) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   986
	seterr(ERROR_INVALID_CMD);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   987
	return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   988
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   989
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   990
    if (!elf->e_ehdr) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   991
	seterr(ERROR_NOEHDR);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   992
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   993
    else if (elf->e_kind != ELF_K_ELF) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   994
	seterr(ERROR_NOTELF);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   995
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   996
    else if (elf->e_class == ELFCLASS32) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   997
	len = _elf32_layout(elf, &flag);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   998
	if (len != -1 && cmd == ELF_C_WRITE && (flag & ELF_F_DIRTY)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   999
	    len = _elf_output(elf, elf->e_fd, (size_t)len, _elf32_write);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
  1000
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
  1001
	return len;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
  1002
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
  1003
#if __LIBELF64
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
  1004
    else if (elf->e_class == ELFCLASS64) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
  1005
	len = _elf64_layout(elf, &flag);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
  1006
	if (len != -1 && cmd == ELF_C_WRITE && (flag & ELF_F_DIRTY)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
  1007
	    len = _elf_output(elf, elf->e_fd, (size_t)len, _elf64_write);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
  1008
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
  1009
	return len;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
  1010
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
  1011
#endif /* __LIBELF64 */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
  1012
    else if (valid_class(elf->e_class)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
  1013
	seterr(ERROR_UNIMPLEMENTED);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
  1014
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
  1015
    else {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
  1016
	seterr(ERROR_UNKNOWN_CLASS);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
  1017
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
  1018
    return -1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
  1019
}