Major progress to getting colorchord on Windows TCC
Give it a shot. colorchord2/windows/compile.bat. I am having issues getting sound in.
This commit is contained in:
parent
ed9ac870c0
commit
4f983efbfe
31 changed files with 4581 additions and 63 deletions
245
colorchord2/windows/symbol_enumerator.c
Normal file
245
colorchord2/windows/symbol_enumerator.c
Normal file
|
@ -0,0 +1,245 @@
|
|||
#include <stdio.h>
|
||||
#include "symbol_enumerator.h"
|
||||
|
||||
#if defined( WIN32 ) || defined( WINDOWS ) || defined( USE_WINDOWS ) || defined( _WIN32 )
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
typedef struct _SYMBOL_INFO {
|
||||
ULONG SizeOfStruct;
|
||||
ULONG TypeIndex;
|
||||
ULONG64 Reserved[2];
|
||||
ULONG Index;
|
||||
ULONG Size;
|
||||
ULONG64 ModBase;
|
||||
ULONG Flags;
|
||||
ULONG64 Value;
|
||||
ULONG64 Address;
|
||||
ULONG Register;
|
||||
ULONG Scope;
|
||||
ULONG Tag;
|
||||
ULONG NameLen;
|
||||
ULONG MaxNameLen;
|
||||
TCHAR Name[1];
|
||||
} SYMBOL_INFO, *PSYMBOL_INFO;
|
||||
typedef struct _IMAGEHLP_STACK_FRAME {
|
||||
ULONG64 InstructionOffset;
|
||||
ULONG64 ReturnOffset;
|
||||
ULONG64 FrameOffset;
|
||||
ULONG64 StackOffset;
|
||||
ULONG64 BackingStoreOffset;
|
||||
ULONG64 FuncTableEntry;
|
||||
ULONG64 Params[4];
|
||||
ULONG64 Reserved[5];
|
||||
BOOL Virtual;
|
||||
ULONG Reserved2;
|
||||
} IMAGEHLP_STACK_FRAME, *PIMAGEHLP_STACK_FRAME;
|
||||
|
||||
|
||||
typedef BOOL (*PSYM_ENUMERATESYMBOLS_CALLBACK)(
|
||||
PSYMBOL_INFO pSymInfo,
|
||||
ULONG SymbolSize,
|
||||
PVOID UserContext
|
||||
);
|
||||
|
||||
BOOL WINAPI SymEnumSymbols(
|
||||
HANDLE hProcess,
|
||||
ULONG64 BaseOfDll,
|
||||
PCTSTR Mask,
|
||||
PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
|
||||
const PVOID UserContext
|
||||
);
|
||||
|
||||
BOOL WINAPI SymInitialize(
|
||||
HANDLE hProcess,
|
||||
PCTSTR UserSearchPath,
|
||||
BOOL fInvadeProcess
|
||||
);
|
||||
|
||||
BOOL WINAPI SymCleanup(
|
||||
HANDLE hProcess
|
||||
);
|
||||
|
||||
BOOL CALLBACK __cdecl mycb(
|
||||
PSYMBOL_INFO pSymInfo,
|
||||
ULONG SymbolSize,
|
||||
PVOID UserContext
|
||||
){
|
||||
SymEnumeratorCallback cb = (SymEnumeratorCallback)UserContext;
|
||||
return !cb( "", &pSymInfo->Name[0], (void*)pSymInfo->Address, (long) pSymInfo->Size );
|
||||
}
|
||||
|
||||
int EnumerateSymbols( SymEnumeratorCallback cb )
|
||||
{
|
||||
HANDLE proc = GetCurrentProcess();
|
||||
if( !SymInitialize( proc, 0, 1 ) ) return -1;
|
||||
if( !SymEnumSymbols( proc, 0, "*!*", &mycb, (void*)cb ) )
|
||||
{
|
||||
SymCleanup(proc);
|
||||
return -2;
|
||||
}
|
||||
SymCleanup(proc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef __GNUC__
|
||||
#define __int128_t long long long
|
||||
#endif
|
||||
|
||||
#include <link.h>
|
||||
#include <elf.h>
|
||||
|
||||
#define UINTS_PER_WORD (__WORDSIZE / (CHAR_BIT * sizeof (unsigned int)))
|
||||
|
||||
|
||||
struct dl_phdr_info {
|
||||
ElfW(Addr) dlpi_addr; /* Base address of object */
|
||||
const char *dlpi_name; /* (Null-terminated) name of
|
||||
object */
|
||||
const ElfW(Phdr) *dlpi_phdr; /* Pointer to array of
|
||||
ELF program headers
|
||||
for this object */
|
||||
ElfW(Half) dlpi_phnum; /* # of items in dlpi_phdr */
|
||||
};
|
||||
|
||||
|
||||
|
||||
void dl_iterate_phdr( void*, void*);
|
||||
|
||||
|
||||
static ElfW(Word) gnu_hashtab_symbol_count(const unsigned int *const table)
|
||||
{
|
||||
const unsigned int *const bucket = table + 4 + table[2] * (unsigned int)(UINTS_PER_WORD);
|
||||
unsigned int b = table[0];
|
||||
unsigned int max = 0U;
|
||||
|
||||
while (b-->0U)
|
||||
if (bucket[b] > max)
|
||||
max = bucket[b];
|
||||
|
||||
return (ElfW(Word))max;
|
||||
}
|
||||
|
||||
static static void *dynamic_pointer(const ElfW(Addr) addr,
|
||||
const ElfW(Addr) base, const ElfW(Phdr) *const header, const ElfW(Half) headers)
|
||||
{
|
||||
if (addr) {
|
||||
ElfW(Half) h;
|
||||
|
||||
for (h = 0; h < headers; h++)
|
||||
if (header[h].p_type == PT_LOAD)
|
||||
if (addr >= base + header[h].p_vaddr &&
|
||||
addr < base + header[h].p_vaddr + header[h].p_memsz)
|
||||
return (void *)addr;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//Mostly based off of http://stackoverflow.com/questions/29903049/get-names-and-addresses-of-exported-functions-from-in-linux
|
||||
static int callback(struct dl_phdr_info *info,
|
||||
size_t size, void *data)
|
||||
{
|
||||
SymEnumeratorCallback cb = (SymEnumeratorCallback)data;
|
||||
const ElfW(Addr) base = info->dlpi_addr;
|
||||
const ElfW(Phdr) *const header = info->dlpi_phdr;
|
||||
const ElfW(Half) headers = info->dlpi_phnum;
|
||||
const char *libpath, *libname;
|
||||
ElfW(Half) h;
|
||||
|
||||
if (info->dlpi_name && info->dlpi_name[0])
|
||||
libpath = info->dlpi_name;
|
||||
else
|
||||
libpath = "";
|
||||
|
||||
libname = strrchr(libpath, '/');
|
||||
|
||||
if (libname && libname[0] == '/' && libname[1])
|
||||
libname++;
|
||||
else
|
||||
libname = libpath;
|
||||
|
||||
for (h = 0; h < headers; h++)
|
||||
{
|
||||
if (header[h].p_type == PT_DYNAMIC)
|
||||
{
|
||||
const ElfW(Dyn) *entry = (const ElfW(Dyn) *)(base + header[h].p_vaddr);
|
||||
const ElfW(Word) *hashtab;
|
||||
const ElfW(Sym) *symtab = NULL;
|
||||
const char *strtab = NULL;
|
||||
ElfW(Word) symbol_count = 0;
|
||||
|
||||
for (; entry->d_tag != DT_NULL; entry++)
|
||||
{
|
||||
switch (entry->d_tag)
|
||||
{
|
||||
case DT_HASH:
|
||||
hashtab = dynamic_pointer(entry->d_un.d_ptr, base, header, headers);
|
||||
if (hashtab)
|
||||
symbol_count = hashtab[1];
|
||||
break;
|
||||
case DT_GNU_HASH:
|
||||
hashtab = dynamic_pointer(entry->d_un.d_ptr, base, header, headers);
|
||||
if (hashtab)
|
||||
{
|
||||
ElfW(Word) count = gnu_hashtab_symbol_count(hashtab);
|
||||
if (count > symbol_count)
|
||||
symbol_count = count;
|
||||
}
|
||||
break;
|
||||
case DT_STRTAB:
|
||||
strtab = dynamic_pointer(entry->d_un.d_ptr, base, header, headers);
|
||||
break;
|
||||
case DT_SYMTAB:
|
||||
symtab = dynamic_pointer(entry->d_un.d_ptr, base, header, headers);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (symtab && strtab && symbol_count > 0) {
|
||||
ElfW(Word) s;
|
||||
|
||||
for (s = 0; s < symbol_count; s++) {
|
||||
const char *name;
|
||||
void *const ptr = dynamic_pointer(base + symtab[s].st_value, base, header, headers);
|
||||
int result;
|
||||
|
||||
if (!ptr)
|
||||
continue;
|
||||
|
||||
if (symtab[s].st_name)
|
||||
name = strtab + symtab[s].st_name;
|
||||
else
|
||||
name = "";
|
||||
|
||||
result = cb( libpath, name, ptr, symtab[s].st_size );
|
||||
if( result ) return result; //Bail early.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int EnumerateSymbols( SymEnumeratorCallback cb )
|
||||
{
|
||||
dl_iterate_phdr( callback, cb );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue