mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-23 12:08:25 +00:00
Make MC use Windows COFF on Windows and add tests.
llvm-svn: 109494
This commit is contained in:
parent
16789d79fe
commit
33ac353ce4
@ -14,6 +14,7 @@
|
||||
#include "llvm/MC/MCAssembler.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
#include "llvm/MC/MCObjectWriter.h"
|
||||
#include "llvm/MC/MCSectionCOFF.h"
|
||||
#include "llvm/MC/MCSectionELF.h"
|
||||
#include "llvm/MC/MCSectionMachO.h"
|
||||
#include "llvm/MC/MachObjectWriter.h"
|
||||
@ -212,6 +213,24 @@ public:
|
||||
: ELFX86AsmBackend(T) {}
|
||||
};
|
||||
|
||||
class WindowsX86AsmBackend : public X86AsmBackend {
|
||||
public:
|
||||
WindowsX86AsmBackend(const Target &T)
|
||||
: X86AsmBackend(T) {
|
||||
HasAbsolutizedSet = true;
|
||||
HasScatteredSymbols = true;
|
||||
}
|
||||
|
||||
MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
|
||||
return createWinCOFFObjectWriter (OS);
|
||||
}
|
||||
|
||||
bool isVirtualSection(const MCSection &Section) const {
|
||||
const MCSectionCOFF &SE = static_cast<const MCSectionCOFF&>(Section);
|
||||
return SE.getCharacteristics() & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA;
|
||||
}
|
||||
};
|
||||
|
||||
class DarwinX86AsmBackend : public X86AsmBackend {
|
||||
public:
|
||||
DarwinX86AsmBackend(const Target &T)
|
||||
@ -290,6 +309,8 @@ TargetAsmBackend *llvm::createX86_32AsmBackend(const Target &T,
|
||||
switch (Triple(TT).getOS()) {
|
||||
case Triple::Darwin:
|
||||
return new DarwinX86_32AsmBackend(T);
|
||||
case Triple::Win32:
|
||||
return new WindowsX86AsmBackend(T);
|
||||
default:
|
||||
return new ELFX86_32AsmBackend(T);
|
||||
}
|
||||
|
@ -46,6 +46,8 @@ static MCStreamer *createMCStreamer(const Target &T, const std::string &TT,
|
||||
bool RelaxAll) {
|
||||
Triple TheTriple(TT);
|
||||
switch (TheTriple.getOS()) {
|
||||
case Triple::Win32:
|
||||
return createWinCOFFStreamer(Ctx, TAB, *_Emitter, _OS);
|
||||
default:
|
||||
return createMachOStreamer(Ctx, TAB, _OS, _Emitter, RelaxAll);
|
||||
}
|
||||
|
136
test/MC/COFF/basic-coff.ll
Normal file
136
test/MC/COFF/basic-coff.ll
Normal file
@ -0,0 +1,136 @@
|
||||
; RUN: llc -filetype=obj %s -o %t
|
||||
; RUN: coff-dump.py %abs_tmp | FileCheck %s
|
||||
|
||||
; ModuleID = '-'
|
||||
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
|
||||
target triple = "i686-pc-win32"
|
||||
|
||||
@.str = private constant [12 x i8] c"Hello World\00" ; <[12 x i8]*> [#uses=1]
|
||||
|
||||
define i32 @main() nounwind {
|
||||
entry:
|
||||
%call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0)) nounwind ; <i32> [#uses=0]
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
declare i32 @printf(i8* nocapture, ...) nounwind
|
||||
|
||||
; CHECK: {
|
||||
; CHECK: MachineType = IMAGE_FILE_MACHINE_I386 (0x14C)
|
||||
; CHECK: NumberOfSections = 2
|
||||
; CHECK: TimeDateStamp = {{[0-9]+}}
|
||||
; CHECK: PointerToSymbolTable = 0x99
|
||||
; CHECK: NumberOfSymbols = 7
|
||||
; CHECK: SizeOfOptionalHeader = 0
|
||||
; CHECK: Characteristics = 0x0
|
||||
; CHECK: Sections = [
|
||||
; CHECK: 0 = {
|
||||
; CHECK: Name = .text
|
||||
; CHECK: VirtualSize = 0
|
||||
; CHECK: VirtualAddress = 0
|
||||
; CHECK: SizeOfRawData = 21
|
||||
; CHECK: PointerToRawData = 0x64
|
||||
; CHECK: PointerToRelocations = 0x79
|
||||
; CHECK: PointerToLineNumbers = 0x0
|
||||
; CHECK: NumberOfRelocations = 2
|
||||
; CHECK: NumberOfLineNumbers = 0
|
||||
; CHECK: Charateristics = 0x60500020
|
||||
; CHECK: IMAGE_SCN_CNT_CODE
|
||||
; CHECK: IMAGE_SCN_ALIGN_16BYTES
|
||||
; CHECK: IMAGE_SCN_MEM_EXECUTE
|
||||
; CHECK: IMAGE_SCN_MEM_READ
|
||||
; CHECK: SectionData =
|
||||
; CHECK: 83 EC 04 C7 04 24 00 00 - 00 00 E8 00 00 00 00 31 |.....$.........1|
|
||||
; CHECK: C0 83 C4 04 C3 |.....|
|
||||
; CHECK: Relocations = [
|
||||
; CHECK: 0 = {
|
||||
; CHECK: VirtualAddress = 0x6
|
||||
; CHECK: SymbolTableIndex = 5
|
||||
; CHECK: Type = IMAGE_REL_I386_DIR32 (6)
|
||||
; CHECK: SymbolName = _main
|
||||
; CHECK: }
|
||||
; CHECK: 1 = {
|
||||
; CHECK: VirtualAddress = 0xB
|
||||
; CHECK: SymbolTableIndex = 6
|
||||
; CHECK: Type = IMAGE_REL_I386_REL32 (20)
|
||||
; CHECK: SymbolName = L_.str
|
||||
; CHECK: }
|
||||
; CHECK: ]
|
||||
; CHECK: }
|
||||
; CHECK: 1 = {
|
||||
; CHECK: Name = .data
|
||||
; CHECK: VirtualSize = 0
|
||||
; CHECK: VirtualAddress = 0
|
||||
; CHECK: SizeOfRawData = 12
|
||||
; CHECK: PointerToRawData = 0x8D
|
||||
; CHECK: PointerToRelocations = 0x0
|
||||
; CHECK: PointerToLineNumbers = 0x0
|
||||
; CHECK: NumberOfRelocations = 0
|
||||
; CHECK: NumberOfLineNumbers = 0
|
||||
; CHECK: Charateristics = 0xC0100040
|
||||
; CHECK: IMAGE_SCN_CNT_INITIALIZED_DATA
|
||||
; CHECK: IMAGE_SCN_ALIGN_1BYTES
|
||||
; CHECK: IMAGE_SCN_MEM_READ
|
||||
; CHECK: IMAGE_SCN_MEM_WRITE
|
||||
; CHECK: SectionData =
|
||||
; CHECK: 48 65 6C 6C 6F 20 57 6F - 72 6C 64 00 |Hello World.|
|
||||
; CHECK: Relocations = None
|
||||
; CHECK: }
|
||||
; CHECK: ]
|
||||
; CHECK: Symbols = [
|
||||
; CHECK: 0 = {
|
||||
; CHECK: Name = .text
|
||||
; CHECK: Value = 0
|
||||
; CHECK: SectionNumber = 1
|
||||
; CHECK: SimpleType = IMAGE_SYM_TYPE_NULL (0)
|
||||
; CHECK: ComplexType = IMAGE_SYM_DTYPE_NULL (0)
|
||||
; CHECK: StorageClass = IMAGE_SYM_CLASS_STATIC (3)
|
||||
; CHECK: NumberOfAuxSymbols = 1
|
||||
; CHECK: AuxillaryData =
|
||||
; CHECK: 15 00 00 00 02 00 00 00 - 00 00 00 00 01 00 00 00 |................|
|
||||
; CHECK: 00 00 |..|
|
||||
; CHECK: }
|
||||
; CHECK: 1 = {
|
||||
; CHECK: Name = .data
|
||||
; CHECK: Value = 0
|
||||
; CHECK: SectionNumber = 2
|
||||
; CHECK: SimpleType = IMAGE_SYM_TYPE_NULL (0)
|
||||
; CHECK: ComplexType = IMAGE_SYM_DTYPE_NULL (0)
|
||||
; CHECK: StorageClass = IMAGE_SYM_CLASS_STATIC (3)
|
||||
; CHECK: NumberOfAuxSymbols = 1
|
||||
; CHECK: AuxillaryData =
|
||||
; CHECK: 0C 00 00 00 00 00 00 00 - 00 00 00 00 02 00 00 00 |................|
|
||||
; CHECK: 00 00 |..|
|
||||
; CHECK: }
|
||||
; CHECK: 2 = {
|
||||
; CHECK: Name = _main
|
||||
; CHECK: Value = 0
|
||||
; CHECK: SectionNumber = 1
|
||||
; CHECK: SimpleType = unknown (32)
|
||||
; CHECK: ComplexType = IMAGE_SYM_DTYPE_NULL (0)
|
||||
; CHECK: StorageClass = IMAGE_SYM_CLASS_EXTERNAL (2)
|
||||
; CHECK: NumberOfAuxSymbols = 0
|
||||
; CHECK: AuxillaryData =
|
||||
; CHECK: }
|
||||
; CHECK: 3 = {
|
||||
; CHECK: Name = L_.str
|
||||
; CHECK: Value = 0
|
||||
; CHECK: SectionNumber = 2
|
||||
; CHECK: SimpleType = IMAGE_SYM_TYPE_NULL (0)
|
||||
; CHECK: ComplexType = IMAGE_SYM_DTYPE_NULL (0)
|
||||
; CHECK: StorageClass = IMAGE_SYM_CLASS_STATIC (3)
|
||||
; CHECK: NumberOfAuxSymbols = 0
|
||||
; CHECK: AuxillaryData =
|
||||
; CHECK: }
|
||||
; CHECK: 4 = {
|
||||
; CHECK: Name = _printf
|
||||
; CHECK: Value = 0
|
||||
; CHECK: SectionNumber = 0
|
||||
; CHECK: SimpleType = IMAGE_SYM_TYPE_NULL (0)
|
||||
; CHECK: ComplexType = IMAGE_SYM_DTYPE_NULL (0)
|
||||
; CHECK: StorageClass = IMAGE_SYM_CLASS_EXTERNAL (2)
|
||||
; CHECK: NumberOfAuxSymbols = 0
|
||||
; CHECK: AuxillaryData =
|
||||
; CHECK: }
|
||||
; CHECK: ]
|
||||
; CHECK: }
|
5
test/MC/COFF/dg.exp
Normal file
5
test/MC/COFF/dg.exp
Normal file
@ -0,0 +1,5 @@
|
||||
load_lib llvm.exp
|
||||
|
||||
if { [llvm_supports_target X86] } {
|
||||
RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll}]]
|
||||
}
|
543
test/Scripts/coff-dump.py
Normal file
543
test/Scripts/coff-dump.py
Normal file
@ -0,0 +1,543 @@
|
||||
#===-- coff-dump.py - COFF object file dump utility-------------------------===#
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file is distributed under the University of Illinois Open Source
|
||||
# License. See LICENSE.TXT for details.
|
||||
#
|
||||
#===------------------------------------------------------------------------===#
|
||||
|
||||
#
|
||||
# COFF File Definition
|
||||
#
|
||||
|
||||
def string_table_entry (offset):
|
||||
return ('ptr', '+ + PointerToSymbolTable * NumberOfSymbols 18 %s' % offset, ('scalar', 'cstr', '%s'))
|
||||
|
||||
def secname(value):
|
||||
if value[0] == '/':
|
||||
return string_table_entry (value [1:].rstrip('\0'))
|
||||
else:
|
||||
return '%s'
|
||||
|
||||
def symname(value):
|
||||
parts = struct.unpack("<2L", value)
|
||||
if parts [0] == 0:
|
||||
return string_table_entry (parts [1])
|
||||
else:
|
||||
return '%s'
|
||||
|
||||
file = ('struct', [
|
||||
('MachineType', ('enum', '<H', '0x%X', {
|
||||
0x0: 'IMAGE_FILE_MACHINE_UNKNOWN',
|
||||
0x1d3: 'IMAGE_FILE_MACHINE_AM33',
|
||||
0x866: 'IMAGE_FILE_MACHINE_AMD64',
|
||||
0x1c0: 'IMAGE_FILE_MACHINE_ARM',
|
||||
0xebc: 'IMAGE_FILE_MACHINE_EBC',
|
||||
0x14c: 'IMAGE_FILE_MACHINE_I386',
|
||||
0x200: 'IMAGE_FILE_MACHINE_IA64',
|
||||
0x904: 'IMAGE_FILE_MACHINE_M32R',
|
||||
0x266: 'IMAGE_FILE_MACHINE_MIPS16',
|
||||
0x366: 'IMAGE_FILE_MACHINE_MIPSFPU',
|
||||
0x466: 'IMAGE_FILE_MACHINE_MIPSFPU16',
|
||||
0x1f0: 'IMAGE_FILE_MACHINE_POWERPC',
|
||||
0x1f1: 'IMAGE_FILE_MACHINE_POWERPCFP',
|
||||
0x166: 'IMAGE_FILE_MACHINE_R4000',
|
||||
0x1a2: 'IMAGE_FILE_MACHINE_SH3',
|
||||
0x1a3: 'IMAGE_FILE_MACHINE_SH3DSP',
|
||||
0x1a6: 'IMAGE_FILE_MACHINE_SH4',
|
||||
0x1a8: 'IMAGE_FILE_MACHINE_SH5',
|
||||
0x1c2: 'IMAGE_FILE_MACHINE_THUMB',
|
||||
0x169: 'IMAGE_FILE_MACHINE_WCEMIPSV2',
|
||||
})),
|
||||
('NumberOfSections', ('scalar', '<H', '%d')),
|
||||
('TimeDateStamp', ('scalar', '<L', '%d')),
|
||||
('PointerToSymbolTable', ('scalar', '<L', '0x%0X')),
|
||||
('NumberOfSymbols', ('scalar', '<L', '%d')),
|
||||
('SizeOfOptionalHeader', ('scalar', '<H', '%d')),
|
||||
('Characteristics', ('flags', '<H', '0x%x', [
|
||||
(0x0001, 'IMAGE_FILE_RELOCS_STRIPPED', ),
|
||||
(0x0002, 'IMAGE_FILE_EXECUTABLE_IMAGE', ),
|
||||
(0x0004, 'IMAGE_FILE_LINE_NUMS_STRIPPED', ),
|
||||
(0x0008, 'IMAGE_FILE_LOCAL_SYMS_STRIPPED', ),
|
||||
(0x0010, 'IMAGE_FILE_AGGRESSIVE_WS_TRIM', ),
|
||||
(0x0020, 'IMAGE_FILE_LARGE_ADDRESS_AWARE', ),
|
||||
(0x0080, 'IMAGE_FILE_BYTES_REVERSED_LO', ),
|
||||
(0x0100, 'IMAGE_FILE_32BIT_MACHINE', ),
|
||||
(0x0200, 'IMAGE_FILE_DEBUG_STRIPPED', ),
|
||||
(0x0400, 'IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP', ),
|
||||
(0x0800, 'IMAGE_FILE_NET_RUN_FROM_SWAP', ),
|
||||
(0x1000, 'IMAGE_FILE_SYSTEM', ),
|
||||
(0x2000, 'IMAGE_FILE_DLL', ),
|
||||
(0x4000, 'IMAGE_FILE_UP_SYSTEM_ONLY', ),
|
||||
(0x8000, 'IMAGE_FILE_BYTES_REVERSED_HI', ),
|
||||
])),
|
||||
('Sections', ('array', 'NumberOfSections', ('struct', [
|
||||
('Name', ('scalar', '<8s', secname)),
|
||||
('VirtualSize', ('scalar', '<L', '%d' )),
|
||||
('VirtualAddress', ('scalar', '<L', '%d' )),
|
||||
('SizeOfRawData', ('scalar', '<L', '%d' )),
|
||||
('PointerToRawData', ('scalar', '<L', '0x%X' )),
|
||||
('PointerToRelocations', ('scalar', '<L', '0x%X' )),
|
||||
('PointerToLineNumbers', ('scalar', '<L', '0x%X' )),
|
||||
('NumberOfRelocations', ('scalar', '<H', '%d' )),
|
||||
('NumberOfLineNumbers', ('scalar', '<H', '%d' )),
|
||||
('Charateristics', ('flags', '<L', '0x%X', [
|
||||
(0x00000008, 'IMAGE_SCN_TYPE_NO_PAD'),
|
||||
(0x00000020, 'IMAGE_SCN_CNT_CODE'),
|
||||
(0x00000040, 'IMAGE_SCN_CNT_INITIALIZED_DATA'),
|
||||
(0x00000080, 'IMAGE_SCN_CNT_UNINITIALIZED_DATA'),
|
||||
(0x00000100, 'IMAGE_SCN_LNK_OTHER'),
|
||||
(0x00000200, 'IMAGE_SCN_LNK_INFO'),
|
||||
(0x00000800, 'IMAGE_SCN_LNK_REMOVE'),
|
||||
(0x00001000, 'IMAGE_SCN_LNK_COMDAT'),
|
||||
(0x00008000, 'IMAGE_SCN_GPREL'),
|
||||
(0x00020000, 'IMAGE_SCN_MEM_PURGEABLE'),
|
||||
(0x00020000, 'IMAGE_SCN_MEM_16BIT'),
|
||||
(0x00040000, 'IMAGE_SCN_MEM_LOCKED'),
|
||||
(0x00080000, 'IMAGE_SCN_MEM_PRELOAD'),
|
||||
(0x00F00000, 'IMAGE_SCN_ALIGN', {
|
||||
0x00100000: 'IMAGE_SCN_ALIGN_1BYTES',
|
||||
0x00200000: 'IMAGE_SCN_ALIGN_2BYTES',
|
||||
0x00300000: 'IMAGE_SCN_ALIGN_4BYTES',
|
||||
0x00400000: 'IMAGE_SCN_ALIGN_8BYTES',
|
||||
0x00500000: 'IMAGE_SCN_ALIGN_16BYTES',
|
||||
0x00600000: 'IMAGE_SCN_ALIGN_32BYTES',
|
||||
0x00700000: 'IMAGE_SCN_ALIGN_64BYTES',
|
||||
0x00800000: 'IMAGE_SCN_ALIGN_128BYTES',
|
||||
0x00900000: 'IMAGE_SCN_ALIGN_256BYTES',
|
||||
0x00A00000: 'IMAGE_SCN_ALIGN_512BYTES',
|
||||
0x00B00000: 'IMAGE_SCN_ALIGN_1024BYTES',
|
||||
0x00C00000: 'IMAGE_SCN_ALIGN_2048BYTES',
|
||||
0x00D00000: 'IMAGE_SCN_ALIGN_4096BYTES',
|
||||
0x00E00000: 'IMAGE_SCN_ALIGN_8192BYTES',
|
||||
}),
|
||||
(0x01000000, 'IMAGE_SCN_LNK_NRELOC_OVFL'),
|
||||
(0x02000000, 'IMAGE_SCN_MEM_DISCARDABLE'),
|
||||
(0x04000000, 'IMAGE_SCN_MEM_NOT_CACHED'),
|
||||
(0x08000000, 'IMAGE_SCN_MEM_NOT_PAGED'),
|
||||
(0x10000000, 'IMAGE_SCN_MEM_SHARED'),
|
||||
(0x20000000, 'IMAGE_SCN_MEM_EXECUTE'),
|
||||
(0x40000000, 'IMAGE_SCN_MEM_READ'),
|
||||
(0x80000000, 'IMAGE_SCN_MEM_WRITE'),
|
||||
])),
|
||||
('SectionData', ('ptr', 'PointerToRawData', ('blob', 'SizeOfRawData'))),
|
||||
('Relocations', ('ptr', 'PointerToRelocations', ('array', 'NumberOfRelocations', ('struct', [
|
||||
('VirtualAddress', ('scalar', '<L', '0x%X')),
|
||||
('SymbolTableIndex', ('scalar', '<L', '%d' )),
|
||||
('Type', ('enum', '<H', '%d', ('MachineType', {
|
||||
0x14c: {
|
||||
0x0000: 'IMAGE_REL_I386_ABSOLUTE',
|
||||
0x0001: 'IMAGE_REL_I386_DIR16',
|
||||
0x0002: 'IMAGE_REL_I386_REL16',
|
||||
0x0006: 'IMAGE_REL_I386_DIR32',
|
||||
0x0007: 'IMAGE_REL_I386_DIR32NB',
|
||||
0x0009: 'IMAGE_REL_I386_SEG12',
|
||||
0x000A: 'IMAGE_REL_I386_SECTION',
|
||||
0x000B: 'IMAGE_REL_I386_SECREL',
|
||||
0x000C: 'IMAGE_REL_I386_TOKEN',
|
||||
0x000D: 'IMAGE_REL_I386_SECREL7',
|
||||
0x0014: 'IMAGE_REL_I386_REL32',
|
||||
},
|
||||
}))),
|
||||
('SymbolName', ('ptr', '+ PointerToSymbolTable * - SymbolTableIndex 1 18', ('scalar', '<8s', symname)))
|
||||
])))),
|
||||
]))),
|
||||
('Symbols', ('ptr', 'PointerToSymbolTable', ('byte-array', '* NumberOfSymbols 18', ('struct', [
|
||||
('Name', ('scalar', '<8s', symname)),
|
||||
('Value', ('scalar', '<L', '%d' )),
|
||||
('SectionNumber', ('scalar', '<H', '%d' )),
|
||||
('SimpleType', ('enum', '<B', '%d', {
|
||||
0: 'IMAGE_SYM_TYPE_NULL',
|
||||
1: 'IMAGE_SYM_TYPE_VOID',
|
||||
2: 'IMAGE_SYM_TYPE_CHAR',
|
||||
3: 'IMAGE_SYM_TYPE_SHORT',
|
||||
4: 'IMAGE_SYM_TYPE_INT',
|
||||
5: 'IMAGE_SYM_TYPE_LONG',
|
||||
6: 'IMAGE_SYM_TYPE_FLOAT',
|
||||
7: 'IMAGE_SYM_TYPE_DOUBLE',
|
||||
8: 'IMAGE_SYM_TYPE_STRUCT',
|
||||
9: 'IMAGE_SYM_TYPE_UNION',
|
||||
10: 'IMAGE_SYM_TYPE_ENUM',
|
||||
11: 'IMAGE_SYM_TYPE_MOE',
|
||||
12: 'IMAGE_SYM_TYPE_BYTE',
|
||||
13: 'IMAGE_SYM_TYPE_WORD',
|
||||
14: 'IMAGE_SYM_TYPE_UINT',
|
||||
15: 'IMAGE_SYM_TYPE_DWORD',
|
||||
})),
|
||||
('ComplexType', ('enum', '<B', '%d', {
|
||||
0: 'IMAGE_SYM_DTYPE_NULL',
|
||||
1: 'IMAGE_SYM_DTYPE_POINTER',
|
||||
2: 'IMAGE_SYM_DTYPE_FUNCTION',
|
||||
3: 'IMAGE_SYM_DTYPE_ARRAY',
|
||||
})),
|
||||
('StorageClass', ('enum', '<B', '%d', {
|
||||
-1: 'IMAGE_SYM_CLASS_END_OF_FUNCTION',
|
||||
0: 'IMAGE_SYM_CLASS_NULL',
|
||||
1: 'IMAGE_SYM_CLASS_AUTOMATIC',
|
||||
2: 'IMAGE_SYM_CLASS_EXTERNAL',
|
||||
3: 'IMAGE_SYM_CLASS_STATIC',
|
||||
4: 'IMAGE_SYM_CLASS_REGISTER',
|
||||
5: 'IMAGE_SYM_CLASS_EXTERNAL_DEF',
|
||||
6: 'IMAGE_SYM_CLASS_LABEL',
|
||||
7: 'IMAGE_SYM_CLASS_UNDEFINED_LABEL',
|
||||
8: 'IMAGE_SYM_CLASS_MEMBER_OF_STRUCT',
|
||||
9: 'IMAGE_SYM_CLASS_ARGUMENT',
|
||||
10: 'IMAGE_SYM_CLASS_STRUCT_TAG',
|
||||
11: 'IMAGE_SYM_CLASS_MEMBER_OF_UNION',
|
||||
12: 'IMAGE_SYM_CLASS_UNION_TAG',
|
||||
13: 'IMAGE_SYM_CLASS_TYPE_DEFINITION',
|
||||
14: 'IMAGE_SYM_CLASS_UNDEFINED_STATIC',
|
||||
15: 'IMAGE_SYM_CLASS_ENUM_TAG',
|
||||
16: 'IMAGE_SYM_CLASS_MEMBER_OF_ENUM',
|
||||
17: 'IMAGE_SYM_CLASS_REGISTER_PARAM',
|
||||
18: 'IMAGE_SYM_CLASS_BIT_FIELD',
|
||||
100: 'IMAGE_SYM_CLASS_BLOCK',
|
||||
101: 'IMAGE_SYM_CLASS_FUNCTION',
|
||||
102: 'IMAGE_SYM_CLASS_END_OF_STRUCT',
|
||||
103: 'IMAGE_SYM_CLASS_FILE',
|
||||
104: 'IMAGE_SYM_CLASS_SECTION',
|
||||
105: 'IMAGE_SYM_CLASS_WEAK_EXTERNAL',
|
||||
107: 'IMAGE_SYM_CLASS_CLR_TOKEN',
|
||||
})),
|
||||
('NumberOfAuxSymbols', ('scalar', '<B', '%d' )),
|
||||
('AuxillaryData', ('blob', '* NumberOfAuxSymbols 18')),
|
||||
])))),
|
||||
])
|
||||
|
||||
#
|
||||
# Definition Interpreter
|
||||
#
|
||||
|
||||
import sys, types, struct, re
|
||||
|
||||
Input = None
|
||||
Stack = []
|
||||
Fields = {}
|
||||
|
||||
Indent = 0
|
||||
NewLine = True
|
||||
|
||||
def indent():
|
||||
global Indent
|
||||
Indent += 1
|
||||
|
||||
def dedent():
|
||||
global Indent
|
||||
Indent -= 1
|
||||
|
||||
def write(input):
|
||||
global NewLine
|
||||
output = ""
|
||||
|
||||
for char in input:
|
||||
|
||||
if NewLine:
|
||||
output += Indent * ' '
|
||||
NewLine = False
|
||||
|
||||
output += char
|
||||
|
||||
if char == '\n':
|
||||
NewLine = True
|
||||
|
||||
sys.stdout.write (output)
|
||||
|
||||
def read(format):
|
||||
return struct.unpack (format, Input.read(struct.calcsize(format)))
|
||||
|
||||
def read_cstr ():
|
||||
output = ""
|
||||
while True:
|
||||
char = Input.read (1)
|
||||
if len (char) == 0:
|
||||
raise RuntimeError ("EOF while reading cstr")
|
||||
if char == '\0':
|
||||
break
|
||||
output += char
|
||||
return output
|
||||
|
||||
def push_pos(seek_to = None):
|
||||
Stack [0:0] = [Input.tell ()]
|
||||
if seek_to:
|
||||
Input.seek (seek_to)
|
||||
|
||||
def pop_pos():
|
||||
assert(len (Stack) > 0)
|
||||
Input.seek (Stack [0])
|
||||
del Stack [0]
|
||||
|
||||
def print_binary_data(size):
|
||||
value = ""
|
||||
while size > 0:
|
||||
if size >= 16:
|
||||
data = Input.read(16)
|
||||
size -= 16
|
||||
else:
|
||||
data = Input.read(size)
|
||||
size = 0
|
||||
value += data
|
||||
bytes = ""
|
||||
text = ""
|
||||
for index in xrange (16):
|
||||
if index < len (data):
|
||||
if index == 8:
|
||||
bytes += "- "
|
||||
ch = ord (data [index])
|
||||
bytes += "%02X " % ch
|
||||
if ch >= 0x20 and ch <= 0x7F:
|
||||
text += data [index]
|
||||
else:
|
||||
text += "."
|
||||
else:
|
||||
if index == 8:
|
||||
bytes += " "
|
||||
bytes += " "
|
||||
|
||||
write ("%s|%s|\n" % (bytes, text))
|
||||
return value
|
||||
|
||||
idlit = re.compile ("[a-zA-Z][a-zA-Z0-9_-]*")
|
||||
numlit = re.compile ("[0-9]+")
|
||||
|
||||
def read_value(expr):
|
||||
|
||||
input = iter (expr.split ())
|
||||
|
||||
def eval():
|
||||
|
||||
token = input.next ()
|
||||
|
||||
if expr == 'cstr':
|
||||
return read_cstr ()
|
||||
if expr == 'true':
|
||||
return True
|
||||
if expr == 'false':
|
||||
return False
|
||||
|
||||
if len (token) > 1 and token [0] in ('=', '@', '<', '!', '>'):
|
||||
val = read(expr)
|
||||
assert (len (val) == 1)
|
||||
return val [0]
|
||||
|
||||
if token == '+':
|
||||
return eval () + eval ()
|
||||
if token == '-':
|
||||
return eval () - eval ()
|
||||
if token == '*':
|
||||
return eval () * eval ()
|
||||
if token == '/':
|
||||
return eval () / eval ()
|
||||
|
||||
if idlit.match (token):
|
||||
return Fields [token]
|
||||
if numlit.match (token):
|
||||
return int (token)
|
||||
|
||||
raise RuntimeError ("unexpected token %s" % repr(token))
|
||||
|
||||
value = eval ()
|
||||
|
||||
try:
|
||||
input.next ()
|
||||
except StopIteration:
|
||||
return value
|
||||
raise RuntimeError("unexpected input at end of expression")
|
||||
|
||||
def write_value(format,value):
|
||||
format_type = type (format)
|
||||
if format_type is types.StringType:
|
||||
write (format%value)
|
||||
elif format_type is types.FunctionType:
|
||||
write_value (format (value), value)
|
||||
elif format_type is types.TupleType:
|
||||
Fields ['this'] = value
|
||||
handle_element (format)
|
||||
else:
|
||||
raise RuntimeError("unexpected type: %s" % repr(format_type))
|
||||
|
||||
def handle_scalar(entry):
|
||||
iformat = entry [1]
|
||||
oformat = entry [2]
|
||||
|
||||
value = read_value (iformat)
|
||||
|
||||
write_value (oformat, value)
|
||||
|
||||
return value
|
||||
|
||||
def handle_enum(entry):
|
||||
iformat = entry [1]
|
||||
oformat = entry [2]
|
||||
definitions = entry [3]
|
||||
|
||||
value = read_value (iformat)
|
||||
|
||||
if type (definitions) is types.TupleType:
|
||||
selector = read_value (definitions [0])
|
||||
definitions = definitions [1] [selector]
|
||||
|
||||
description = definitions[value] if value in definitions else "unknown"
|
||||
|
||||
write ("%s (" % description)
|
||||
write_value (oformat, value)
|
||||
write (")")
|
||||
|
||||
return value
|
||||
|
||||
def handle_flags(entry):
|
||||
iformat = entry [1]
|
||||
oformat = entry [2]
|
||||
definitions = entry [3]
|
||||
|
||||
value = read_value (iformat)
|
||||
|
||||
write_value (oformat, value)
|
||||
|
||||
indent ()
|
||||
for entry in definitions:
|
||||
mask = entry [0]
|
||||
name = entry [1]
|
||||
if len (entry) == 3:
|
||||
map = entry [2]
|
||||
selection = value & mask
|
||||
if selection in map:
|
||||
write("\n%s" % map[selection])
|
||||
else:
|
||||
write("\n%s <%d>" % (name, selection))
|
||||
elif len (entry) == 2:
|
||||
if value & mask != 0:
|
||||
write("\n%s" % name)
|
||||
dedent ()
|
||||
|
||||
return value
|
||||
|
||||
def handle_struct(entry):
|
||||
global Fields
|
||||
members = entry [1]
|
||||
|
||||
newFields = {}
|
||||
|
||||
write ("{\n");
|
||||
indent ()
|
||||
|
||||
for member in members:
|
||||
name = member [0]
|
||||
type = member [1]
|
||||
|
||||
write("%s = "%name.ljust(24))
|
||||
|
||||
value = handle_element(type)
|
||||
|
||||
write("\n")
|
||||
|
||||
Fields [name] = value
|
||||
newFields [name] = value
|
||||
|
||||
dedent ()
|
||||
write ("}")
|
||||
|
||||
return newFields
|
||||
|
||||
def handle_array(entry):
|
||||
length = entry [1]
|
||||
element = entry [2]
|
||||
|
||||
newItems = []
|
||||
|
||||
write ("[\n")
|
||||
indent ()
|
||||
|
||||
value = read_value (length)
|
||||
|
||||
for index in xrange (value):
|
||||
write ("%d = "%index)
|
||||
value = handle_element(element)
|
||||
write ("\n")
|
||||
newItems.append (value)
|
||||
|
||||
dedent ()
|
||||
write ("]")
|
||||
|
||||
return newItems
|
||||
|
||||
def handle_byte_array(entry):
|
||||
length = entry [1]
|
||||
element = entry [2]
|
||||
|
||||
newItems = []
|
||||
|
||||
write ("[\n")
|
||||
indent ()
|
||||
|
||||
value = read_value (length)
|
||||
end_of_array = Input.tell () + value
|
||||
|
||||
index = 0
|
||||
while Input.tell () < end_of_array:
|
||||
write ("%d = "%index)
|
||||
value = handle_element(element)
|
||||
write ("\n")
|
||||
newItems.append (value)
|
||||
index += 1
|
||||
|
||||
dedent ()
|
||||
write ("]")
|
||||
|
||||
return newItems
|
||||
|
||||
def handle_ptr(entry):
|
||||
offset = entry[1]
|
||||
element = entry [2]
|
||||
|
||||
value = None
|
||||
offset = read_value (offset)
|
||||
|
||||
if offset != 0:
|
||||
|
||||
push_pos (offset)
|
||||
|
||||
value = handle_element (element)
|
||||
|
||||
pop_pos ()
|
||||
|
||||
else:
|
||||
write ("None")
|
||||
|
||||
return value
|
||||
|
||||
def handle_blob(entry):
|
||||
length = entry [1]
|
||||
|
||||
write ("\n")
|
||||
indent ()
|
||||
|
||||
value = print_binary_data (read_value (length))
|
||||
|
||||
dedent ()
|
||||
|
||||
return value
|
||||
|
||||
def handle_element(entry):
|
||||
handlers = {
|
||||
'struct': handle_struct,
|
||||
'scalar': handle_scalar,
|
||||
'enum': handle_enum,
|
||||
'flags': handle_flags,
|
||||
'ptr': handle_ptr,
|
||||
'blob': handle_blob,
|
||||
'array': handle_array,
|
||||
'byte-array': handle_byte_array,
|
||||
}
|
||||
|
||||
if not entry [0] in handlers:
|
||||
raise RuntimeError ("unexpected type '%s'" % str (entry[0]))
|
||||
|
||||
return handlers [entry [0]] (entry)
|
||||
|
||||
Input = open (sys.argv [1], "rb")
|
||||
try:
|
||||
handle_element (file)
|
||||
finally:
|
||||
Input.close ()
|
||||
Input = None
|
4
test/Scripts/coff-dump.py.bat
Normal file
4
test/Scripts/coff-dump.py.bat
Normal file
@ -0,0 +1,4 @@
|
||||
@echo off
|
||||
|
||||
%PYTHON_EXECUTABLE% %LLVM_SRC_ROOT%\test\Scripts\coff-dump.py %1 %2 %3 %4 %5 %6 %7 %8 %9
|
||||
|
Loading…
Reference in New Issue
Block a user