How about reading pdb?
llvm offers some info about it,
The PDB File FormatI hope that we can discuss about it in here and we find out what it can offer to
PellesC users.
An open discussion about it.
EDIT:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <stdint.h>
//#include "msf.h"
// https://llvm.org/docs/PDB/MsfFile.html
const char Magic[] = "Microsoft C/C++ MSF 7.00\r\n\x1a\x44\x53\0\0";
typedef struct SuperBlock {
char FileMagic[32]; //sizeof(Magic)];
uint32_t BlockSize;
uint32_t FreeBlockMapBlock;
uint32_t NumBlocks;
uint32_t NumDirectoryBytes;
uint32_t Unknown;
uint32_t BlockMapAddr;
}SUPERBLOCK,*PSUPERBLOCK;
typedef struct StreamDirectory {
uint32_t NumStreams;
uint32_t StreamSizes; //[NumStreams];
uint32_t StreamBlocks[]; //[NumStreams][];
}STREAMDIRECTORY,*PSTREAMDIRECTORY;
int ProcessFile(PBYTE pMem);
int main(int argc, char **argv)
{
HANDLE hFile, hMapping;
VOID *pMem;
if (argc < 2) {
puts("Usage: TestMsf.exe <file>");
return 1;
}
hFile = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (hMapping)
{
pMem = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
if (pMem)
{
ProcessFile(pMem);
UnmapViewOfFile(pMem);
} else
puts("File open error");
CloseHandle(hMapping);
} else
puts("FileMapping error");
CloseHandle(hFile);
}
else
puts("File open error");
return 0;
}
/*
Old Directory Fixed Stream Index 0 Previous MSF Stream Directory
PDB Stream Fixed Stream Index 1 Basic File Information
TPI Stream Fixed Stream Index 2 CodeView Type Records
DBI Stream Fixed Stream Index 3 Module/Compiland Information
IPI Stream Fixed Stream Index 4 CodeView Type Records
*/
int ProcessFile(PBYTE pMem)
{
SUPERBLOCK *pMsfHdr = (SUPERBLOCK*)pMem;
printf("FileMagic: %s\n", pMsfHdr->FileMagic);
printf("BlockSize: %u\n", pMsfHdr->BlockSize);
printf("FreeBlockMapBlock: %u -> %Xh\n", pMsfHdr->FreeBlockMapBlock,
pMsfHdr->FreeBlockMapBlock*pMsfHdr->BlockSize);
printf("NumBlocks: %u\n", pMsfHdr->NumBlocks);
printf("NumDirectoryBytes: %u\n", pMsfHdr->NumDirectoryBytes);
printf("Unknown: %u\n", pMsfHdr->Unknown);
printf("BlockMapAddr: %u -> %Xh\n", pMsfHdr->BlockMapAddr,
pMsfHdr->BlockMapAddr*pMsfHdr->BlockSize);
printf("\nfilesize: %u\n", pMsfHdr->BlockSize*pMsfHdr->NumBlocks);
DWORD *pIndexes = (DWORD*)(pMem+pMsfHdr->BlockMapAddr*pMsfHdr->BlockSize);
DWORD *pIndex = pIndexes; // the first Index Block
printf("\nStreamDir indexes:");
while (*pIndex)
printf("%04Xh", *pIndex++);
pIndex = pIndexes; // the first Index Block
printf("\nStreamDir Block %u -> %Xh\n", *pIndex, *pIndex*pMsfHdr->BlockSize);
PSTREAMDIRECTORY pStreamDir = (PSTREAMDIRECTORY)(pMem+*pIndex*pMsfHdr->BlockSize);
printf("NumStreams %u\n", pStreamDir->NumStreams);
DWORD nStreams = pStreamDir->NumStreams;
DWORD nStreamBlocks = pMsfHdr->NumDirectoryBytes/4-1-pStreamDir->NumStreams;
printf("Number of stream blocks %u\n", nStreamBlocks);
//DWORD *pDW = (DWORD*)&pStreamDir->StreamSizes;
DWORD *pStreamSizes = &pStreamDir->StreamSizes;
printf("StreamSizes[%u] = ", nStreams);
for (DWORD nC=0; nC<nStreams; nC++)
printf("%d ", pStreamSizes[nC]);
printf("\nStreamBlocks[%u] =", nStreamBlocks);
DWORD *pStreamBlocks = &pStreamDir->StreamSizes;
pStreamBlocks += nStreams;
for (DWORD nC=0; nC<nStreamBlocks; nC++)
printf(" %2d", pStreamBlocks[nC]);
printf("\n ");
for (DWORD nC=0; nC<nStreams; nC++) {
//int nBlocks = pStreamSizes[nC]/nBlockSize+(pStreamSizes[nC]%nBlockSize?1:0);
int nBlocks;
if (pStreamSizes[nC]>0 && pStreamSizes[nC]<0xFFFFFFFF) // -1 free block
nBlocks = (pStreamSizes[nC]-1)/nBlockSize+1;
else nBlocks = 0;
if (nBlocks) {
printf("%2d %u {", nStream, nBlocks);
int nBlk1 = nBlkCnt;
for (int i=0; i<nBlocks; i++) {
if (i) printf(",");
printf("%d", pStreamBlocks[nBlkCnt++]);
}
printf("} %u bytes -> %Xh\n", pStreamSizes[nC], pStreamBlocks[nBlk1]*nBlockSize);
} else printf("%2d %u\n", nStream, nBlocks);
nStream++;
}
return 0;
}
EDIT 2018-07-05: TestPdb_a2 avoid to show wrong stream blocks.
EDIT 2018-07-06: TestPdb_a2 fixed streams.