You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
153 lines
4.2 KiB
153 lines
4.2 KiB
/*
|
|
* Copyright 2002-2019 Intel Corporation.
|
|
*
|
|
* This software is provided to you as Sample Source Code as defined in the accompanying
|
|
* End User License Agreement for the Intel(R) Software Development Products ("Agreement")
|
|
* section 1.L.
|
|
*
|
|
* This software and the related documents are provided as is, with no express or implied
|
|
* warranties, other than those that are expressly stated in the License.
|
|
*/
|
|
|
|
/*! @file
|
|
Test pin calculation for the IMG size as obtained from IMG_LowAddress and
|
|
IMG_HighAddress APIs and compare the size to the value computed from the ELF file.
|
|
This test verify the fix for Mantis #4735.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <sys/fcntl.h>
|
|
#include <elf.h>
|
|
#include "pin.H"
|
|
|
|
using namespace std;
|
|
|
|
/* ===================================================================== */
|
|
|
|
/* ===================================================================== */
|
|
|
|
int ValidEhdr(Elf64_Ehdr *ehdr)
|
|
{
|
|
if (sizeof(Elf64_Ehdr) != ehdr->e_ehsize)
|
|
return 0;
|
|
|
|
if ((ehdr->e_ident[ EI_MAG0 ] != ELFMAG0 ) ||
|
|
(ehdr->e_ident[ EI_MAG1 ] != ELFMAG1 ) ||
|
|
(ehdr->e_ident[ EI_MAG2 ] != ELFMAG2 ) ||
|
|
(ehdr->e_ident[ EI_MAG3 ] != ELFMAG3 ))
|
|
return 0;
|
|
|
|
// supports only 64 bits
|
|
return(ehdr->e_machine == EM_X86_64);
|
|
}
|
|
|
|
INT64 CalcSize(const char *imgname, BOOL text_only)
|
|
{
|
|
ADDRINT baseAddr = 0;
|
|
BOOL set = false;
|
|
INT64 memSize = 0;
|
|
Elf64_Ehdr ehdr;
|
|
Elf64_Phdr *phdr;
|
|
int res, i, fd;
|
|
|
|
fd = open(imgname, O_RDONLY, 0);
|
|
if (fd < 0)
|
|
return 0;
|
|
|
|
res = read(fd, &ehdr, sizeof(ehdr));
|
|
if (res != sizeof(ehdr) || !ValidEhdr(&ehdr))
|
|
{
|
|
// The file is not a legal ELF image
|
|
close(fd);
|
|
return 0;
|
|
}
|
|
|
|
// Read program headers
|
|
phdr = (Elf64_Phdr *)malloc(sizeof(Elf64_Phdr) * ehdr.e_phnum);
|
|
lseek(fd, ehdr.e_phoff, SEEK_SET);
|
|
read(fd, phdr, ehdr.e_phnum * sizeof(phdr[0]));
|
|
|
|
// find the lowest vaddr of loadable segmenta
|
|
for (i = 0; i < ehdr.e_phnum; i++)
|
|
{
|
|
if (phdr[i].p_type == PT_LOAD)
|
|
{
|
|
if (text_only && (phdr[i].p_flags & PF_W)!=0)
|
|
continue;
|
|
if (!set || phdr[i].p_vaddr < baseAddr)
|
|
{
|
|
set = true;
|
|
baseAddr = phdr[i].p_vaddr;
|
|
}
|
|
}
|
|
}
|
|
|
|
// find the size based on distance from base address and mem size
|
|
for (i = 0; i < ehdr.e_phnum; i++)
|
|
{
|
|
if (phdr[i].p_type == PT_LOAD)
|
|
{
|
|
ADDRINT endAddr = phdr[i].p_vaddr + phdr[i].p_memsz;
|
|
if (text_only && (phdr[i].p_flags & PF_W)!=0)
|
|
continue;
|
|
|
|
if (memSize < (INT64)(endAddr - baseAddr))
|
|
{
|
|
memSize = endAddr - baseAddr;
|
|
}
|
|
}
|
|
}
|
|
|
|
free(phdr);
|
|
close(fd);
|
|
return memSize-1;
|
|
}
|
|
|
|
VOID ImageLoad(IMG img, VOID *v)
|
|
{
|
|
ADDRINT imgLow = IMG_LowAddress(img);
|
|
ADDRINT imgHigh = IMG_HighAddress(img);
|
|
string imgName = IMG_Name(img);
|
|
INT64 calc_size = 0;
|
|
|
|
if (imgName.find("vdso") != string::npos)
|
|
return;
|
|
|
|
if (IMG_NumRegions(img) == 1)
|
|
{
|
|
calc_size = CalcSize(imgName.c_str(), false);
|
|
// fprintf(stderr, "Img: %-30s: 1 Region: %p %p expected size: %lld got %lld\n",
|
|
// imgName.c_str(), (void*)imgLow, (void*)imgHigh, (long long)calc_size, (long long)(imgHigh-imgLow));
|
|
}
|
|
else
|
|
{
|
|
calc_size = CalcSize(imgName.c_str(), true);
|
|
// fprintf(stderr, "Img: %-30s: %d Region: %p %p expected size: %lld got %lld\n", imgName.c_str(),
|
|
// IMG_NumRegions(img), (void*)imgLow, (void*)imgHigh, (long long)calc_size, (long long)(imgHigh-imgLow));
|
|
}
|
|
|
|
if (calc_size != (INT64)(imgHigh-imgLow))
|
|
{
|
|
fprintf(stderr, "ERROR: Img: %-30s: expected size: %lld got %lld\n", imgName.c_str(),
|
|
(long long)calc_size, (long long)(imgHigh-imgLow));
|
|
}
|
|
}
|
|
|
|
/* ===================================================================== */
|
|
|
|
int main(int argc, CHAR *argv[])
|
|
{
|
|
PIN_InitSymbols();
|
|
PIN_Init(argc,argv);
|
|
|
|
IMG_AddInstrumentFunction(ImageLoad, NULL);
|
|
|
|
PIN_StartProgramProbed();
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* ===================================================================== */
|
|
/* eof */
|
|
/* ===================================================================== */
|