int pmelf_getsym64(Elf_Stream s, Elf64_Sym *psym) { if ( 1 != SREAD(psym, sizeof(*psym), 1, s) ) { return -1; } if ( s->needswap ) { #ifdef PMELF_CONFIG_NO_SWAPSUPPORT return -2; #else elf_swap32( &psym->st_name); elf_swap16( &psym->st_shndx); elf_swap64( &psym->st_value); elf_swap64( &psym->st_size); #endif } #ifdef PARANOIA_ON { int x; if ( (x = ELF64_ST_TYPE( psym->st_info )) > STT_MAXSUP ) { PMELF_PRINTF( pmelf_err, PMELF_PRE"pmelf_getsym - paranoia: unsupported type %i\n", x); return -1; } if ( (x = ELF64_ST_BIND( psym->st_info )) > STB_MAXSUP ) { PMELF_PRINTF( pmelf_err, PMELF_PRE"pmelf_getsym - paranoia: unsupported binding %i\n", x); return -1; } } #endif return 0; }
int pmelf_putehdr64(Elf_Stream s, Elf64_Ehdr *pehdr) { uint8_t magic[4] = { ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3 }; Elf64_Ehdr nehdr; if ( memcmp(magic, pehdr->e_ident+EI_MAG0, sizeof(magic)) ) { PMELF_PRINTF(pmelf_err, PMELF_PRE"error: not an ELF file\n"); return -1; } if ( pehdr->e_ident[EI_CLASS] != ELFCLASS64 ) { PMELF_PRINTF(pmelf_err, PMELF_PRE"error: not an 64-bit ELF file\n"); return -1; } if ( pehdr->e_ident[EI_VERSION] != EV_CURRENT ) { PMELF_PRINTF(pmelf_err, PMELF_PRE"error: not a version %i ELF file\n", EV_CURRENT); return -1; } s->needswap = iamlsb() ^ (pehdr->e_ident[EI_DATA] == ELFDATA2LSB ? 1 : 0); #ifdef PMELF_CONFIG_NO_SWAPSUPPORT if ( s->needswap ) { PMELF_PRINTF(pmelf_err, PMELF_PRE"error: host/target byte order mismatch but pmelf was configured w/o support for byte-swapping\n"); return -2; } #else if ( s->needswap ) { nehdr = *pehdr; pehdr = &nehdr; elf_swap16( &pehdr->e_type ); elf_swap16( &pehdr->e_machine ); elf_swap32( &pehdr->e_version ); elf_swap64( &pehdr->e_entry ); elf_swap64( &pehdr->e_phoff ); elf_swap64( &pehdr->e_shoff ); elf_swap32( &pehdr->e_flags ); elf_swap16( &pehdr->e_ehsize ); elf_swap16( &pehdr->e_phentsize ); elf_swap16( &pehdr->e_phnum ); elf_swap16( &pehdr->e_shentsize ); elf_swap16( &pehdr->e_shnum ); elf_swap16( &pehdr->e_shstrndx ); } #endif return s->write && 1 == SWRITE(pehdr, sizeof(*pehdr), 1, s) ? 0 : -1; }
int pmelf_putsym64(Elf_Stream s, Elf64_Sym *psym) { Elf64_Sym nsym; if ( s->needswap ) { #ifdef PMELF_CONFIG_NO_SWAPSUPPORT return -2; #else nsym = *psym; psym = &nsym; elf_swap32( &psym->st_name); elf_swap64( &psym->st_value); elf_swap64( &psym->st_size); elf_swap16( &psym->st_shndx); #endif } return s->write && 1 == SWRITE( psym, sizeof(*psym), 1, s) ? 0 : -1; }
int pmelf_putshdr64(Elf_Stream s, Elf64_Shdr *pshdr) { Elf64_Shdr nshdr; if ( s->needswap ) { #ifdef PMELF_CONFIG_NO_SWAPSUPPORT return -2; #else nshdr = *pshdr; pshdr = &nshdr; elf_swap32( &pshdr->sh_name); elf_swap32( &pshdr->sh_type); elf_swap64( &pshdr->sh_flags); elf_swap64( &pshdr->sh_addr); elf_swap64( &pshdr->sh_offset); elf_swap64( &pshdr->sh_size); elf_swap32( &pshdr->sh_link); elf_swap32( &pshdr->sh_info); elf_swap64( &pshdr->sh_addralign); elf_swap64( &pshdr->sh_entsize); #endif } return s->write && 1 == SWRITE( pshdr, sizeof(*pshdr), 1, s) ? 0 : -1; }