Files
QNX/lib/elf/libelfswap.c
2025-08-20 19:02:58 +08:00

287 lines
5.7 KiB
C

/*
* $QNXLicenseC:
* Copyright 2007, QNX Software Systems. All Rights Reserved.
*
* You must obtain a written license from and pay applicable license fees to QNX
* Software Systems before you may reproduce, modify or distribute this software,
* or any work that includes all or part of this software. Free development
* licenses are available for evaluation and non-commercial purposes. For more
* information visit http://licensing.qnx.com or email licensing@qnx.com.
*
* This file may contain contributions from others. Please review this entire
* file for other proprietary rights or license notices, as well as the QNX
* Development Suite License Guide at http://licensing.qnx.com/license-guide/
* for other information.
* $
*/
#include <lib/compat.h>
#ifdef _NTO_HDR_DIR_
#define _PLATFORM(x) x
#define PLATFORM(x) <_PLATFORM(x)/sys/platform.h>
#include PLATFORM(_NTO_HDR_DIR_)
#endif
#include <inttypes.h>
#include <libelf_int.h>
// stolen from elfdump program
#define _DEBUG
void swap_16( void *ptr )
{
unsigned char tmp, *p = ptr;
tmp = p[0]; p[0] = p[1]; p[1] = tmp;
}
void swap_32( void *ptr )
{
unsigned char tmp, *p = ptr;
tmp = p[0]; p[0] = p[3]; p[3] = tmp;
tmp = p[1]; p[1] = p[2]; p[2] = tmp;
}
// only for wcc and qnx4/x86
// #define __X86__
static
int big_endian( Elf *elf )
{
int xlat;
xlat = 0;
switch( elf->e_ehdrp->e_ident[ EI_DATA ])
{
case ELFDATA2LSB:
#if defined(__BIGENDIAN__ )
xlat = 1;
#endif
#ifdef DEBUG
printf( "\nElf32_getehdr(): LE ==> %s (host)", xlat ? "BE" : "LE" );
flushall();
#endif
break;
case ELFDATA2MSB:
#if defined(__LITTLEENDIAN__ ) || defined(__X86__)
xlat = 1;
#endif
#ifdef DEBUG
printf( "\nElf32_getehdr(): BE ==> %s (host)", !xlat ? "BE" : "LE" );
flushall();
#endif
break;
default:
break;
}
return xlat;
}
//static
int Elf32_swapEhdr( Elf *elf, Elf32_Ehdr *ehdr )
{
#ifdef DEBUG
printf( "\nElf32_swapEhdr()" );
flushall();
#endif
if( !ehdr )
ehdr = elf->e_ehdrp;
elf->xlat = big_endian( elf );
if( elf->xlat )
{
/*
printf( "\ntype=%d", ehdr->e_type );
flushall();
*/
swap_16( &ehdr->e_type );
/*
printf( "\ntype=%d", ehdr->e_type );
flushall();
*/
swap_16( &ehdr->e_machine );
swap_32( &ehdr->e_version );
swap_32( &ehdr->e_entry );
swap_32( &ehdr->e_phoff );
swap_32( &ehdr->e_shoff );
swap_32( &ehdr->e_flags );
swap_16( &ehdr->e_ehsize );
swap_16( &ehdr->e_phentsize );
swap_16( &ehdr->e_phnum );
swap_16( &ehdr->e_shentsize );
swap_16( &ehdr->e_shnum );
swap_16( &ehdr->e_shstrndx );
}
return 0;
}
//static
int Elf32_swapPhdr( Elf *elf )
{
Elf32_Phdr *phdr = elf->e_phdrp;
long count = elf->e_ehdrp->e_phnum;
long num;
#ifdef DEBUG
printf( "\nElf32_swapPhdr()" );
flushall();
#endif
if( elf->xlat )
{
for( num = count; num--; phdr++ )
{
swap_32( &phdr->p_type );
swap_32( &phdr->p_offset );
swap_32( &phdr->p_vaddr );
swap_32( &phdr->p_paddr );
swap_32( &phdr->p_filesz );
swap_32( &phdr->p_memsz );
swap_32( &phdr->p_flags );
swap_32( &phdr->p_align );
}
}
return 0;
}
//static
int Elf32_swapShdr( Elf *elf, Elf32_Shdr *shdr, int count )
{
long num;
#ifdef DEBUG
/*
printf( "\nElf32_swapShdr()" );
flushall();
*/
#endif
if( elf->xlat )
{
for( num = count; num--; shdr++ )
{
swap_32( &shdr->sh_name );
swap_32( &shdr->sh_type );
swap_32( &shdr->sh_flags );
swap_32( &shdr->sh_addr );
swap_32( &shdr->sh_offset );
swap_32( &shdr->sh_size );
swap_32( &shdr->sh_link );
swap_32( &shdr->sh_info );
swap_32( &shdr->sh_addralign );
swap_32( &shdr->sh_entsize );
}
}
return 0;
}
// confusing names Elf32_swapRel() or Elf32_swapRela()!!!
int Elf32_swapRel( Elf *elf, Elf32_Rela *rel, int use_rela )
{
if( elf->xlat )
{
swap_32( &rel->r_offset );
swap_32( &rel->r_info );
if( use_rela )
{
swap_32( &rel->r_addend );
}
}
return 0;
}
//static
int Elf32_swapRela( Elf *elf, char *buf, long size, int use_rela )
{
long num;
long count;
if( elf->xlat )
{
unsigned relsize = ( use_rela ? sizeof( Elf32_Rela ) : sizeof( Elf32_Rel ));
count = size / relsize;
for( num = count; num--; buf += relsize )
{
Elf32_Rela *rel = (Elf32_Rela *)buf;
swap_32( &rel->r_offset );
swap_32( &rel->r_info );
if( use_rela )
{
swap_32( &rel->r_addend );
}
}
}
return 0;
}
int Elf32_swapSym( Elf *elf, Elf32_Sym *sym, long size )
{
long num;
long count;
#ifdef DEBUG
printf( "\nElf32_swapSym()-%d", elf->xlat );
flushall();
#endif
if( elf->xlat )
{
count = size / sizeof( Elf32_Sym );
for( num = count; num--; sym++ )
{
swap_32( &sym->st_name );
swap_32( &sym->st_value );
swap_32( &sym->st_size );
swap_16( &sym->st_shndx );
}
}
return 0;
}
int Elf32_swapDyn( Elf *elf, Elf32_Dyn *dyn )
{
#ifdef DEBUG
printf( "\nElf32_swapDyn()-%d", elf->xlat );
flushall();
#endif
if( elf->xlat )
{
swap_32( &dyn->d_tag );
swap_32( &dyn->d_un );
}
return 0;
}