tools/elf4rom/libs/libelf-0.8.10/lib/cook.c
author Martin Trojer <martin.trojer@nokia.com>
Fri, 15 Jan 2010 09:07:44 +0000
changeset 34 92d87f2e53c2
permissions -rwxr-xr-x
Added ELF4ROM and e32test-driver
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
 * cook.c - read and translate ELF files.
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: cook.c,v 1.28 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
const Elf_Scn _elf_scn_init = INIT_SCN;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    27
const Scn_Data _elf_data_init = INIT_DATA;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    28
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    29
Elf_Type
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    30
_elf_scn_type(unsigned t) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    31
    switch (t) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    32
	case SHT_DYNAMIC:       return ELF_T_DYN;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    33
	case SHT_DYNSYM:        return ELF_T_SYM;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    34
	case SHT_HASH:          return ELF_T_WORD;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    35
	case SHT_REL:           return ELF_T_REL;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    36
	case SHT_RELA:          return ELF_T_RELA;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    37
	case SHT_SYMTAB:        return ELF_T_SYM;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    38
	case SHT_SYMTAB_SHNDX:	return ELF_T_WORD;	/* XXX: really? */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    39
#if __LIBELF_SYMBOL_VERSIONS
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    40
#if __LIBELF_SUN_SYMBOL_VERSIONS
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    41
	case SHT_SUNW_verdef:   return ELF_T_VDEF;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    42
	case SHT_SUNW_verneed:  return ELF_T_VNEED;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    43
	case SHT_SUNW_versym:   return ELF_T_HALF;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    44
#else /* __LIBELF_SUN_SYMBOL_VERSIONS */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    45
	case SHT_GNU_verdef:    return ELF_T_VDEF;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    46
	case SHT_GNU_verneed:   return ELF_T_VNEED;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    47
	case SHT_GNU_versym:    return ELF_T_HALF;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    48
#endif /* __LIBELF_SUN_SYMBOL_VERSIONS */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    49
#endif /* __LIBELF_SYMBOL_VERSIONS */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    50
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    51
    return ELF_T_BYTE;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    52
}
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
/*
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    55
 * Check for overflow on 32-bit systems
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    56
 */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    57
#define overflow(a,b,t)	(sizeof(a) < sizeof(t) && (t)(a) != (b))
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
#define truncerr(t) ((t)==ELF_T_EHDR?ERROR_TRUNC_EHDR:	\
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    60
		    ((t)==ELF_T_PHDR?ERROR_TRUNC_PHDR:	\
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    61
		    ERROR_INTERNAL))
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    62
#define memerr(t)   ((t)==ELF_T_EHDR?ERROR_MEM_EHDR:	\
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    63
		    ((t)==ELF_T_PHDR?ERROR_MEM_PHDR:	\
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    64
		    ERROR_INTERNAL))
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    65
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    66
Elf_Data*
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    67
_elf_xlatetom(const Elf *elf, Elf_Data *dst, const Elf_Data *src) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    68
    if (elf->e_class == ELFCLASS32) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    69
	return elf32_xlatetom(dst, src, elf->e_encoding);
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
#if __LIBELF64
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    72
    else if (elf->e_class == ELFCLASS64) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    73
	return elf64_xlatetom(dst, src, elf->e_encoding);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    74
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    75
#endif /* __LIBELF64 */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    76
    seterr(ERROR_UNIMPLEMENTED);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    77
    return NULL;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    78
}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    79
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    80
static char*
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    81
_elf_item(void *buf, Elf *elf, Elf_Type type, size_t off) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    82
    Elf_Data src, dst;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    83
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    84
    elf_assert(valid_type(type));
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    85
    if (off < 0 || off > elf->e_size) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    86
	seterr(ERROR_OUTSIDE);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    87
	return NULL;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    88
    }
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
    src.d_type = type;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    91
    src.d_version = elf->e_version;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    92
    src.d_size = _fsize(elf->e_class, src.d_version, type);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    93
    elf_assert(src.d_size);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    94
    if ((elf->e_size - off) < src.d_size) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    95
	seterr(truncerr(type));
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    96
	return NULL;
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
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
    99
    dst.d_version = _elf_version;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   100
    dst.d_size = _msize(elf->e_class, dst.d_version, type);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   101
    elf_assert(dst.d_size);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   102
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   103
    if (!(dst.d_buf = buf) && !(dst.d_buf = malloc(dst.d_size))) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   104
	seterr(memerr(type));
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   105
	return NULL;
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
    elf_assert(elf->e_data);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   109
    if (elf->e_rawdata) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   110
	src.d_buf = elf->e_rawdata + off;
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
    else {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   113
	src.d_buf = elf->e_data + off;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   114
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   115
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   116
    if (_elf_xlatetom(elf, &dst, &src)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   117
	return (char*)dst.d_buf;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   118
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   119
    if (dst.d_buf != buf) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   120
	free(dst.d_buf);
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
    return NULL;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   123
}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   124
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   125
static int
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   126
_elf_cook_phdr(Elf *elf) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   127
    size_t num, off, entsz;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   128
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   129
    if (elf->e_class == ELFCLASS32) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   130
	num = ((Elf32_Ehdr*)elf->e_ehdr)->e_phnum;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   131
	off = ((Elf32_Ehdr*)elf->e_ehdr)->e_phoff;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   132
	entsz = ((Elf32_Ehdr*)elf->e_ehdr)->e_phentsize;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   133
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   134
#if __LIBELF64
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   135
    else if (elf->e_class == ELFCLASS64) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   136
	num = ((Elf64_Ehdr*)elf->e_ehdr)->e_phnum;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   137
	off = ((Elf64_Ehdr*)elf->e_ehdr)->e_phoff;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   138
	entsz = ((Elf64_Ehdr*)elf->e_ehdr)->e_phentsize;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   139
	/*
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   140
	 * Check for overflow on 32-bit systems
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   141
	 */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   142
	if (overflow(off, ((Elf64_Ehdr*)elf->e_ehdr)->e_phoff, Elf64_Off)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   143
	    seterr(ERROR_OUTSIDE);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   144
	    return 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   145
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   146
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   147
#endif /* __LIBELF64 */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   148
    else {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   149
	seterr(ERROR_UNIMPLEMENTED);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   150
	return 0;
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
    if (off) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   153
	Elf_Scn *scn;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   154
	size_t size;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   155
	unsigned i;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   156
	char *p;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   157
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   158
	if (num == PN_XNUM) {
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
	     * Overflow in ehdr->e_phnum.
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   161
	     * Get real value from first SHDR.
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   162
	     */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   163
	    if (!(scn = elf->e_scn_1)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   164
		seterr(ERROR_NOSUCHSCN);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   165
		return 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   166
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   167
	    if (elf->e_class == ELFCLASS32) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   168
		num = scn->s_shdr32.sh_info;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   169
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   170
#if __LIBELF64
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   171
	    else if (elf->e_class == ELFCLASS64) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   172
		num = scn->s_shdr64.sh_info;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   173
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   174
#endif /* __LIBELF64 */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   175
	    /* we already had this
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   176
	    else {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   177
		seterr(ERROR_UNIMPLEMENTED);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   178
		return 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   179
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   180
	    */
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
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   183
	size = _fsize(elf->e_class, elf->e_version, ELF_T_PHDR);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   184
	elf_assert(size);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   185
#if ENABLE_EXTENDED_FORMAT
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   186
	if (entsz < size) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   187
#else /* ENABLE_EXTENDED_FORMAT */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   188
	if (entsz != size) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   189
#endif /* ENABLE_EXTENDED_FORMAT */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   190
	    seterr(ERROR_EHDR_PHENTSIZE);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   191
	    return 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   192
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   193
	size = _msize(elf->e_class, _elf_version, ELF_T_PHDR);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   194
	elf_assert(size);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   195
	if (!(p = malloc(num * size))) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   196
	    seterr(memerr(ELF_T_PHDR));
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   197
	    return 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   198
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   199
	for (i = 0; i < num; i++) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   200
	    if (!_elf_item(p + i * size, elf, ELF_T_PHDR, off + i * entsz)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   201
		free(p);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   202
		return 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   203
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   204
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   205
	elf->e_phdr = p;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   206
	elf->e_phnum = num;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   207
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   208
    return 1;
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
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   211
static int
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   212
_elf_cook_shdr(Elf *elf) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   213
    size_t num, off, entsz;
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
    if (elf->e_class == ELFCLASS32) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   216
	num = ((Elf32_Ehdr*)elf->e_ehdr)->e_shnum;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   217
	off = ((Elf32_Ehdr*)elf->e_ehdr)->e_shoff;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   218
	entsz = ((Elf32_Ehdr*)elf->e_ehdr)->e_shentsize;
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
#if __LIBELF64
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   221
    else if (elf->e_class == ELFCLASS64) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   222
	num = ((Elf64_Ehdr*)elf->e_ehdr)->e_shnum;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   223
	off = ((Elf64_Ehdr*)elf->e_ehdr)->e_shoff;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   224
	entsz = ((Elf64_Ehdr*)elf->e_ehdr)->e_shentsize;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   225
	/*
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   226
	 * Check for overflow on 32-bit systems
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
	if (overflow(off, ((Elf64_Ehdr*)elf->e_ehdr)->e_shoff, Elf64_Off)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   229
	    seterr(ERROR_OUTSIDE);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   230
	    return 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   231
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   232
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   233
#endif /* __LIBELF64 */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   234
    else {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   235
	seterr(ERROR_UNIMPLEMENTED);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   236
	return 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   237
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   238
    if (off) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   239
	struct tmp {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   240
	    Elf_Scn	scn;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   241
	    Scn_Data	data;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   242
	} *head;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   243
	Elf_Data src, dst;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   244
	Elf_Scn *scn;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   245
	Scn_Data *sd;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   246
	unsigned i;
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
	if (off < 0 || off > elf->e_size) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   249
	    seterr(ERROR_OUTSIDE);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   250
	    return 0;
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
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   253
	src.d_type = ELF_T_SHDR;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   254
	src.d_version = elf->e_version;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   255
	src.d_size = _fsize(elf->e_class, src.d_version, ELF_T_SHDR);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   256
	elf_assert(src.d_size);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   257
#if ENABLE_EXTENDED_FORMAT
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   258
	if (entsz < src.d_size) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   259
#else /* ENABLE_EXTENDED_FORMAT */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   260
	if (entsz != src.d_size) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   261
#endif /* ENABLE_EXTENDED_FORMAT */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   262
	    seterr(ERROR_EHDR_SHENTSIZE);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   263
	    return 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   264
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   265
	dst.d_version = EV_CURRENT;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   266
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   267
	if (num == 0) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   268
	    union {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   269
		Elf32_Shdr sh32;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   270
#if __LIBELF64
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   271
		Elf64_Shdr sh64;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   272
#endif /* __LIBELF64 */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   273
	    } u;
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
	    /*
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   276
	     * Overflow in ehdr->e_shnum.
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   277
	     * Get real value from first SHDR.
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   278
	     */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   279
	    if (elf->e_size - off < entsz) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   280
		seterr(ERROR_TRUNC_SHDR);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   281
		return 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   282
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   283
	    if (elf->e_rawdata) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   284
		src.d_buf = elf->e_rawdata + off;
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
		src.d_buf = elf->e_data + off;
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
	    dst.d_buf = &u;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   290
	    dst.d_size = sizeof(u);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   291
	    if (!_elf_xlatetom(elf, &dst, &src)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   292
		return 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   293
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   294
	    elf_assert(dst.d_size == _msize(elf->e_class, EV_CURRENT, ELF_T_SHDR));
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   295
	    elf_assert(dst.d_type == ELF_T_SHDR);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   296
	    if (elf->e_class == ELFCLASS32) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   297
		num = u.sh32.sh_size;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   298
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   299
#if __LIBELF64
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   300
	    else if (elf->e_class == ELFCLASS64) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   301
		num = u.sh64.sh_size;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   302
		/*
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   303
		 * Check for overflow on 32-bit systems
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
		if (overflow(num, u.sh64.sh_size, Elf64_Xword)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   306
		    seterr(ERROR_OUTSIDE);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   307
		    return 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   308
		}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   309
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   310
#endif /* __LIBELF64 */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   311
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   312
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   313
	if ((elf->e_size - off) / entsz < num) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   314
	    seterr(ERROR_TRUNC_SHDR);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   315
	    return 0;
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
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   318
	if (!(head = (struct tmp*)malloc(num * sizeof(struct tmp)))) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   319
	    seterr(ERROR_MEM_SCN);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   320
	    return 0;
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
	for (scn = NULL, i = num; i-- > 0; ) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   323
	    head[i].scn = _elf_scn_init;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   324
	    head[i].data = _elf_data_init;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   325
	    head[i].scn.s_link = scn;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   326
	    if (!scn) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   327
		elf->e_scn_n = &head[i].scn;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   328
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   329
	    scn = &head[i].scn;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   330
	    sd = &head[i].data;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   331
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   332
	    if (elf->e_rawdata) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   333
		src.d_buf = elf->e_rawdata + off + i * entsz;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   334
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   335
	    else {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   336
		src.d_buf = elf->e_data + off + i * entsz;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   337
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   338
	    dst.d_buf = &scn->s_uhdr;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   339
	    dst.d_size = sizeof(scn->s_uhdr);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   340
	    if (!_elf_xlatetom(elf, &dst, &src)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   341
		elf->e_scn_n = NULL;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   342
		free(head);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   343
		return 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   344
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   345
	    elf_assert(dst.d_size == _msize(elf->e_class, EV_CURRENT, ELF_T_SHDR));
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   346
	    elf_assert(dst.d_type == ELF_T_SHDR);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   347
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   348
	    scn->s_elf = elf;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   349
	    scn->s_index = i;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   350
	    scn->s_data_1 = sd;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   351
	    scn->s_data_n = sd;
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
	    sd->sd_scn = scn;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   354
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   355
	    if (elf->e_class == ELFCLASS32) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   356
		Elf32_Shdr *shdr = &scn->s_shdr32;
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
		scn->s_type = shdr->sh_type;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   359
		scn->s_size = shdr->sh_size;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   360
		scn->s_offset = shdr->sh_offset;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   361
		sd->sd_data.d_align = shdr->sh_addralign;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   362
		sd->sd_data.d_type = _elf_scn_type(scn->s_type);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   363
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   364
#if __LIBELF64
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   365
	    else if (elf->e_class == ELFCLASS64) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   366
		Elf64_Shdr *shdr = &scn->s_shdr64;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   367
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   368
		scn->s_type = shdr->sh_type;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   369
		scn->s_size = shdr->sh_size;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   370
		scn->s_offset = shdr->sh_offset;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   371
		sd->sd_data.d_align = shdr->sh_addralign;
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
		 * Check for overflow on 32-bit systems
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   374
		 */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   375
		if (overflow(scn->s_size, shdr->sh_size, Elf64_Xword)
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   376
		 || overflow(scn->s_offset, shdr->sh_offset, Elf64_Off)
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   377
		 || overflow(sd->sd_data.d_align, shdr->sh_addralign, Elf64_Xword)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   378
		    seterr(ERROR_OUTSIDE);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   379
		    return 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   380
		}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   381
		sd->sd_data.d_type = _elf_scn_type(scn->s_type);
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
		 * QUIRKS MODE:
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   384
		 *
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   385
		 * Some 64-bit architectures use 64-bit entries in the
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   386
		 * .hash section. This violates the ELF standard, and
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   387
		 * should be fixed. It's mostly harmless as long as the
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   388
		 * binary and the machine running your program have the
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   389
		 * same byte order, but you're in trouble if they don't,
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   390
		 * and if the entry size is wrong.
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   391
		 *
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   392
		 * As a workaround, I let libelf guess the right size
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   393
		 * for the binary. This relies pretty much on the fact
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   394
		 * that the binary provides correct data in the section
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   395
		 * headers. If it doesn't, it's probably broken anyway.
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   396
		 * Therefore, libelf uses a standard conforming value
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   397
		 * when it's not absolutely sure.
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   398
		 */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   399
		if (scn->s_type == SHT_HASH) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   400
		    int override = 0;
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
		    /*
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   403
		     * sh_entsize must reflect the entry size
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   404
		     */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   405
		    if (shdr->sh_entsize == ELF64_FSZ_ADDR) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   406
			override++;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   407
		    }
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
		     * sh_size must be a multiple of sh_entsize
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   410
		     */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   411
		    if (shdr->sh_size % ELF64_FSZ_ADDR == 0) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   412
			override++;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   413
		    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   414
		    /*
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   415
		     * There must be room for at least 2 entries
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
		    if (shdr->sh_size >= 2 * ELF64_FSZ_ADDR) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   418
			override++;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   419
		    }
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
		     * sh_addralign must be correctly set
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
		    if (shdr->sh_addralign == ELF64_FSZ_ADDR) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   424
			override++;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   425
		    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   426
		    /*
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   427
		     * The section must be properly aligned
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   428
		     */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   429
		    if (shdr->sh_offset % ELF64_FSZ_ADDR == 0) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   430
			override++;
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
		    /* XXX: also look at the data? */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   433
		    /*
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   434
		     * Make a conservative decision...
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   435
		     */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   436
		    if (override >= 5) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   437
			sd->sd_data.d_type = ELF_T_ADDR;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   438
		    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   439
		}
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
		 * END QUIRKS MODE.
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   442
		 */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   443
	    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   444
#endif /* __LIBELF64 */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   445
	    /* we already had this
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
		seterr(ERROR_UNIMPLEMENTED);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   448
		return 0;
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
	    */
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   451
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   452
	    sd->sd_data.d_size = scn->s_size;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   453
	    sd->sd_data.d_version = _elf_version;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   454
	}
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   455
	elf_assert(scn == &head[0].scn);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   456
	elf->e_scn_1 = &head[0].scn;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   457
	head[0].scn.s_freeme = 1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   458
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   459
    return 1;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   460
}
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
static int
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   463
_elf_cook_file(Elf *elf) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   464
    elf->e_ehdr = _elf_item(NULL, elf, ELF_T_EHDR, 0);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   465
    if (!elf->e_ehdr) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   466
	return 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   467
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   468
    /*
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   469
     * Note: _elf_cook_phdr may require the first section header!
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
    if (!_elf_cook_shdr(elf)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   472
	return 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   473
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   474
    if (!_elf_cook_phdr(elf)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   475
	return 0;
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
    return 1;
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
int
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   481
_elf_cook(Elf *elf) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   482
    elf_assert(_elf_scn_init.s_magic == SCN_MAGIC);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   483
    elf_assert(_elf_data_init.sd_magic == DATA_MAGIC);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   484
    elf_assert(elf);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   485
    elf_assert(elf->e_magic == ELF_MAGIC);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   486
    elf_assert(elf->e_kind == ELF_K_ELF);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   487
    elf_assert(!elf->e_ehdr);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   488
    if (!valid_version(elf->e_version)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   489
	seterr(ERROR_UNKNOWN_VERSION);
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
    else if (!valid_encoding(elf->e_encoding)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   492
	seterr(ERROR_UNKNOWN_ENCODING);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   493
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   494
    else if (valid_class(elf->e_class)) {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   495
	return _elf_cook_file(elf);
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
    else {
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   498
	seterr(ERROR_UNKNOWN_CLASS);
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   499
    }
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   500
    return 0;
92d87f2e53c2 Added ELF4ROM and e32test-driver
Martin Trojer <martin.trojer@nokia.com>
parents:
diff changeset
   501
}