summaryrefslogtreecommitdiffstats
path: root/src/PEImage.h
blob: ce8e80477deb54c694c1d609dd61f62301d15a31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// Convert DMD CodeView debug information to PDB files

// Copyright (c) 2009-2010 by Rainer Schuetze, All Rights Reserved

//

// License for redistribution is given by the Artistic License 2.0

// see file LICENSE for further details


#ifndef __PEIMAGE_H__

#define __PEIMAGE_H__


#include "LastError.h"


#include <windows.h>


struct OMFDirHeader;
struct OMFDirEntry;

#define IMGHDR(x) (hdr32 ? hdr32->x : hdr64->x)


class PEImage : public LastError
{
public:
	PEImage(const TCHAR* iname = 0);
	~PEImage();

	template<class P> P* DP(int off) const
	{
		return (P*) ((char*) dump_base + off);
	}
	template<class P> P* DPV(int off, int size) const
	{
		if(off < 0 || off + size > dump_total_len)
			return 0;
		return (P*) ((char*) dump_base + off);
	}
	template<class P> P* DPV(int off) const
	{
		return DPV<P>(off, sizeof(P));
	}
	template<class P> P* CVP(int off) const
	{
		return DPV<P>(cv_base + off, sizeof(P));
	}

	template<class P> P* RVA(unsigned long rva, int len)
	{
		IMAGE_DOS_HEADER *dos = DPV<IMAGE_DOS_HEADER> (0);
		IMAGE_NT_HEADERS32* hdr = DPV<IMAGE_NT_HEADERS32> (dos->e_lfanew);
		IMAGE_SECTION_HEADER* sec = IMAGE_FIRST_SECTION(hdr);

		for (int i = 0; i < hdr->FileHeader.NumberOfSections; i++)
		{
			if (rva       >= sec[i].VirtualAddress &&
				rva + len <= sec[i].VirtualAddress + sec[i].SizeOfRawData)
				return DPV<P>(sec[i].PointerToRawData + rva - sec[i].VirtualAddress, len);
		}
		return 0;
	}

	bool readAll(const TCHAR* iname);
	bool loadExe(const TCHAR* iname);
	bool loadObj(const TCHAR* iname);
	bool save(const TCHAR* oname);

	bool replaceDebugSection (const void* data, int datalen, bool initCV);
	bool initCVPtr(bool initDbgDir);
	bool initDbgPtr(bool initDbgDir);
	bool initDWARFPtr(bool initDbgDir);
    bool initDWARFObject();
    void initDWARFSegments();
	bool relocateDebugLineInfo(unsigned int img_base);

	bool hasDWARF() const { return debug_line != 0; }
	bool isX64() const { return hdr64 != 0; }
	bool isDBG() const { return dbgfile; }

	int countCVEntries() const;
	OMFDirEntry* getCVEntry(int i) const;

	int getCVSize() const { return dbgDir->SizeOfData; }

	// utilities

	static void* alloc_aligned(unsigned int size, unsigned int align, unsigned int alignoff = 0);
	static void free_aligned(void* p);

	int countSections() const { return nsec; }
	int findSection(unsigned int off) const;
	int findSymbol(const char* name, unsigned long& off) const;
	const char* findSectionSymbolName(int s) const;
	const IMAGE_SECTION_HEADER& getSection(int s) const { return sec[s]; }
	unsigned long long getImageBase() const { return IMGHDR(OptionalHeader.ImageBase); }
    int getRelocationInLineSegment(unsigned int offset) const;
    int getRelocationInSegment(int segment, unsigned int offset) const;
	bool areDebugSymbolsStripped() const { return (IMGHDR(FileHeader.Characteristics) & IMAGE_FILE_DEBUG_STRIPPED) != 0; }
    int dumpDebugLineInfoCOFF();
    int dumpDebugLineInfoOMF();

private:
    template<typename SYM> const char* t_findSectionSymbolName(int s) const;

	int fd;
	void* dump_base;
	int dump_total_len;

	// codeview

	IMAGE_DOS_HEADER *dos;
	IMAGE_NT_HEADERS32* hdr32;
	IMAGE_NT_HEADERS64* hdr64;
	IMAGE_SECTION_HEADER* sec;
	IMAGE_DEBUG_DIRECTORY* dbgDir;
	OMFDirHeader* dirHeader;
	OMFDirEntry* dirEntry;
    int nsec;
    int nsym;
    const char* symtable;
    const char* strtable;
    bool bigobj;
    bool dbgfile; // is DBG file


public:
	//dwarf

	char* debug_aranges;
	char* debug_pubnames;
	char* debug_pubtypes;
	char* debug_info;     unsigned long debug_info_length;
	char* debug_abbrev;   unsigned long debug_abbrev_length;
	char* debug_line;     unsigned long debug_line_length;
	char* debug_frame;    unsigned long debug_frame_length;
	char* debug_str;
	char* debug_loc;      unsigned long debug_loc_length;
	char* debug_ranges;   unsigned long debug_ranges_length;
	char* reloc;          unsigned long reloc_length;

	int linesSegment;
	int codeSegment;
	int cv_base;
};


#endif //__PEIMAGE_H__