Index: kernel/generic/include/udebug/udebug.h
===================================================================
--- kernel/generic/include/udebug/udebug.h	(revision e515b21a3fde67534b9cb58f7237e854904ccba2)
+++ kernel/generic/include/udebug/udebug.h	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
@@ -107,4 +107,17 @@
  */
 UDEBUG_M_THREAD_READ,
+
+/** Read the name of the debugged task.
+ *
+ * - ARG2 - destination address in the caller's address space
+ * - ARG3 - size of receiving buffer in bytes
+ *
+ * The kernel fills the buffer with a non-terminated string.
+ *
+ * - ARG2 - number of bytes that were actually copied
+ * - ARG3 - number of bytes of the complete data
+ *
+ */
+UDEBUG_M_NAME_READ,
 
 /** Read the list of the debugged task's address space areas.
Index: kernel/generic/include/udebug/udebug_ops.h
===================================================================
--- kernel/generic/include/udebug/udebug_ops.h	(revision e515b21a3fde67534b9cb58f7237e854904ccba2)
+++ kernel/generic/include/udebug/udebug_ops.h	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
@@ -47,4 +47,5 @@
 int udebug_thread_read(void **buffer, size_t buf_size, size_t *stored,
     size_t *needed);
+int udebug_name_read(char **data, size_t *data_size);
 int udebug_args_read(thread_t *t, void **buffer);
 
Index: kernel/generic/src/udebug/udebug_ipc.c
===================================================================
--- kernel/generic/src/udebug/udebug_ipc.c	(revision e515b21a3fde67534b9cb58f7237e854904ccba2)
+++ kernel/generic/src/udebug/udebug_ipc.c	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
@@ -198,4 +198,50 @@
 	IPC_SET_ARG3(call->data, needed);
 	call->buffer = buffer;
+
+	ipc_answer(&TASK->kb.box, call);
+}
+
+/** Process a NAME_READ call.
+ *
+ * Returns a string containing the name of the task.
+ *
+ * @param call	The call structure.
+ */
+static void udebug_receive_name_read(call_t *call)
+{
+	unative_t uspace_addr;
+	unative_t to_copy;
+	size_t data_size;
+	size_t buf_size;
+	void *data;
+
+	uspace_addr = IPC_GET_ARG2(call->data);	/* Destination address */
+	buf_size = IPC_GET_ARG3(call->data);	/* Dest. buffer size */
+
+	/*
+	 * Read task name.
+	 */
+	udebug_name_read((char **) &data, &data_size);
+
+	/* Copy MAX(buf_size, data_size) bytes */
+
+	if (buf_size > data_size)
+		to_copy = data_size;
+	else
+		to_copy = buf_size;
+
+	/*
+	 * Make use of call->buffer to transfer data to caller's userspace
+	 */
+
+	IPC_SET_RETVAL(call->data, 0);
+	/* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
+	   same code in process_answer() can be used 
+	   (no way to distinguish method in answer) */
+	IPC_SET_ARG1(call->data, uspace_addr);
+	IPC_SET_ARG2(call->data, to_copy);
+
+	IPC_SET_ARG3(call->data, data_size);
+	call->buffer = data;
 
 	ipc_answer(&TASK->kb.box, call);
@@ -409,4 +455,7 @@
 		udebug_receive_thread_read(call);
 		break;
+	case UDEBUG_M_NAME_READ:
+		udebug_receive_name_read(call);
+		break;
 	case UDEBUG_M_AREAS_READ:
 		udebug_receive_areas_read(call);
Index: kernel/generic/src/udebug/udebug_ops.c
===================================================================
--- kernel/generic/src/udebug/udebug_ops.c	(revision e515b21a3fde67534b9cb58f7237e854904ccba2)
+++ kernel/generic/src/udebug/udebug_ops.c	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
@@ -46,4 +46,5 @@
 #include <errno.h>
 #include <print.h>
+#include <string.h>
 #include <syscall/copy.h>
 #include <ipc/ipc.h>
@@ -439,4 +440,27 @@
 }
 
+/** Read task name.
+ *
+ * Returns task name as non-terminated string in a newly allocated buffer.
+ * Also returns the size of the data.
+ *
+ * @param data		Place to store pointer to newly allocated block.
+ * @param data_size	Place to store size of the data.
+ *
+ * @returns		EOK.
+ */
+int udebug_name_read(char **data, size_t *data_size)
+{
+	size_t name_size;
+
+	name_size = str_size(TASK->name) + 1;
+	*data = malloc(name_size, 0);
+	*data_size = name_size;
+
+	memcpy(*data, TASK->name, name_size);
+
+	return 0;
+}
+
 /** Read the arguments of a system call.
  *
Index: uspace/app/taskdump/Makefile
===================================================================
--- uspace/app/taskdump/Makefile	(revision e515b21a3fde67534b9cb58f7237e854904ccba2)
+++ uspace/app/taskdump/Makefile	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
@@ -34,5 +34,6 @@
 
 SOURCES = \
-	taskdump.c
+	taskdump.c \
+	symtab.c
 
 include ../Makefile.common
Index: uspace/app/taskdump/include/elf.h
===================================================================
--- uspace/app/taskdump/include/elf.h	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
+++ uspace/app/taskdump/include/elf.h	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) 2006 Sergey Bondari
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup generic	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef ELF_H_
+#define ELF_H_
+
+#include <arch/elf.h>
+#include <sys/types.h>
+
+/**
+ * current ELF version
+ */
+#define	EV_CURRENT	1
+
+/** 
+ * ELF types 
+ */
+#define ET_NONE		0	/* No type */
+#define ET_REL		1	/* Relocatable file */
+#define ET_EXEC		2	/* Executable */
+#define ET_DYN		3	/* Shared object */
+#define ET_CORE		4	/* Core */
+#define ET_LOPROC	0xff00	/* Processor specific */
+#define ET_HIPROC	0xffff	/* Processor specific */
+
+/** 
+ * ELF machine types
+ */
+#define EM_NO		0	/* No machine */
+#define EM_SPARC	2	/* SPARC */
+#define EM_386		3	/* i386 */
+#define EM_MIPS		8	/* MIPS RS3000 */
+#define EM_MIPS_RS3_LE	10	/* MIPS RS3000 LE */
+#define EM_PPC		20	/* PPC32 */
+#define EM_PPC64	21	/* PPC64 */
+#define EM_ARM		40	/* ARM */
+#define EM_SPARCV9	43	/* SPARC64 */
+#define EM_IA_64	50	/* IA-64 */
+#define EM_X86_64	62	/* AMD64/EMT64 */
+
+/**
+ * ELF identification indexes
+ */
+#define EI_MAG0		0
+#define EI_MAG1		1
+#define EI_MAG2		2
+#define EI_MAG3		3
+#define EI_CLASS	4		/* File class */
+#define EI_DATA		5		/* Data encoding */
+#define EI_VERSION	6		/* File version */
+#define EI_OSABI	7
+#define EI_ABIVERSION	8
+#define EI_PAD		9		/* Start of padding bytes */
+#define EI_NIDENT	16		/* ELF identification table size */
+
+/**
+ * ELF magic number
+ */
+#define ELFMAG0		0x7f
+#define ELFMAG1		'E'
+#define ELFMAG2		'L'
+#define ELFMAG3		'F'
+
+/**
+ * ELF file classes
+ */
+#define ELFCLASSNONE	0
+#define ELFCLASS32	1
+#define ELFCLASS64	2
+
+/**
+ * ELF data encoding types
+ */
+#define ELFDATANONE	0
+#define ELFDATA2LSB	1		/* Least significant byte first (little endian) */
+#define ELFDATA2MSB	2		/* Most signigicant byte first (big endian) */
+
+/**
+ * ELF error return codes
+ */
+#define EE_OK			0	/* No error */
+#define EE_INVALID		1	/* Invalid ELF image */
+#define	EE_MEMORY		2	/* Cannot allocate address space */
+#define EE_INCOMPATIBLE		3	/* ELF image is not compatible with current architecture */
+#define EE_UNSUPPORTED		4	/* Non-supported ELF (e.g. dynamic ELFs) */
+#define EE_IRRECOVERABLE	5
+
+/**
+ * ELF section types
+ */
+#define SHT_NULL		0
+#define SHT_PROGBITS		1
+#define SHT_SYMTAB		2
+#define SHT_STRTAB		3
+#define SHT_RELA		4
+#define SHT_HASH		5
+#define SHT_DYNAMIC		6
+#define SHT_NOTE		7
+#define SHT_NOBITS		8
+#define SHT_REL			9
+#define SHT_SHLIB		10
+#define SHT_DYNSYM		11
+#define SHT_LOOS		0x60000000
+#define SHT_HIOS		0x6fffffff
+#define SHT_LOPROC		0x70000000
+#define SHT_HIPROC		0x7fffffff
+#define SHT_LOUSER		0x80000000
+#define SHT_HIUSER		0xffffffff
+
+/**
+ * ELF section flags
+ */
+#define SHF_WRITE		0x1 
+#define SHF_ALLOC		0x2
+#define SHF_EXECINSTR		0x4
+#define SHF_TLS			0x400
+#define SHF_MASKPROC		0xf0000000
+
+/**
+ * Symbol binding
+ */
+#define STB_LOCAL		0
+#define STB_GLOBAL		1
+#define STB_WEAK		2
+#define STB_LOPROC		13
+#define STB_HIPROC		15
+
+/**
+ * Symbol types
+ */
+#define STT_NOTYPE		0
+#define STT_OBJECT		1
+#define STT_FUNC		2
+#define STT_SECTION		3
+#define STT_FILE		4
+#define STT_LOPROC		13
+#define STT_HIPROC		15
+
+/**
+ * Program segment types
+ */
+#define PT_NULL			0
+#define PT_LOAD			1
+#define PT_DYNAMIC		2
+#define PT_INTERP		3
+#define PT_NOTE			4
+#define PT_SHLIB		5
+#define PT_PHDR			6
+#define PT_LOPROC		0x70000000
+#define PT_HIPROC		0x7fffffff
+
+/**
+ * Program segment attributes.
+ */
+#define PF_X	1
+#define PF_W	2
+#define PF_R	4
+
+/**
+ * ELF data types
+ *
+ * These types are found to be identical in both 32-bit and 64-bit
+ * ELF object file specifications. They are the only types used
+ * in ELF header.
+ */
+typedef uint64_t elf_xword;
+typedef int64_t elf_sxword;
+typedef uint32_t elf_word;
+typedef int32_t elf_sword;
+typedef uint16_t elf_half;
+
+/**
+ * 32-bit ELF data types.
+ *
+ * These types are specific for 32-bit format.
+ */
+typedef uint32_t elf32_addr;
+typedef uint32_t elf32_off;
+
+/**
+ * 64-bit ELF data types.
+ *
+ * These types are specific for 64-bit format.
+ */
+typedef uint64_t elf64_addr;
+typedef uint64_t elf64_off;
+
+/** ELF header */
+struct elf32_header {
+	uint8_t e_ident[EI_NIDENT];
+	elf_half e_type;
+	elf_half e_machine;
+	elf_word e_version;
+	elf32_addr e_entry;
+	elf32_off e_phoff;
+	elf32_off e_shoff;
+	elf_word e_flags;
+	elf_half e_ehsize;
+	elf_half e_phentsize;
+	elf_half e_phnum;
+	elf_half e_shentsize;
+	elf_half e_shnum;
+	elf_half e_shstrndx;
+};
+struct elf64_header {
+	uint8_t e_ident[EI_NIDENT];
+	elf_half e_type;
+	elf_half e_machine;
+	elf_word e_version;
+	elf64_addr e_entry;
+	elf64_off e_phoff;
+	elf64_off e_shoff;
+	elf_word e_flags;
+	elf_half e_ehsize;
+	elf_half e_phentsize;
+	elf_half e_phnum;
+	elf_half e_shentsize;
+	elf_half e_shnum;
+	elf_half e_shstrndx;
+};
+
+/*
+ * ELF segment header.
+ * Segments headers are also known as program headers.
+ */
+struct elf32_segment_header {
+	elf_word p_type;
+	elf32_off p_offset;
+	elf32_addr p_vaddr;
+	elf32_addr p_paddr;
+	elf_word p_filesz;
+	elf_word p_memsz;
+	elf_word p_flags;
+	elf_word p_align;
+};
+struct elf64_segment_header {
+	elf_word p_type;
+	elf_word p_flags;
+	elf64_off p_offset;
+	elf64_addr p_vaddr;
+	elf64_addr p_paddr;
+	elf_xword p_filesz;
+	elf_xword p_memsz;
+	elf_xword p_align;
+};
+
+/*
+ * ELF section header
+ */
+struct elf32_section_header {
+	elf_word sh_name;
+	elf_word sh_type;
+	elf_word sh_flags;
+	elf32_addr sh_addr;
+	elf32_off sh_offset;
+	elf_word sh_size;
+	elf_word sh_link;
+	elf_word sh_info;
+	elf_word sh_addralign;
+	elf_word sh_entsize;
+};
+struct elf64_section_header {
+	elf_word sh_name;
+	elf_word sh_type;
+	elf_xword sh_flags;
+	elf64_addr sh_addr;
+	elf64_off sh_offset;
+	elf_xword sh_size;
+	elf_word sh_link;
+	elf_word sh_info;
+	elf_xword sh_addralign;
+	elf_xword sh_entsize;
+};
+
+/*
+ * ELF symbol table entry
+ */
+struct elf32_symbol {
+	elf_word st_name;
+	elf32_addr st_value;
+	elf_word st_size;
+	uint8_t st_info;
+	uint8_t st_other;
+	elf_half st_shndx;
+};
+struct elf64_symbol {
+	elf_word st_name;
+	uint8_t st_info;
+	uint8_t st_other;
+	elf_half st_shndx;
+	elf64_addr st_value;
+	elf_xword st_size;
+};
+
+#ifdef __32_BITS__ 
+typedef struct elf32_header elf_header_t;
+typedef struct elf32_segment_header elf_segment_header_t;
+typedef struct elf32_section_header elf_section_header_t;
+typedef struct elf32_symbol elf_symbol_t;
+#endif
+#ifdef __64_BITS__
+typedef struct elf64_header elf_header_t;
+typedef struct elf64_segment_header elf_segment_header_t;
+typedef struct elf64_section_header elf_section_header_t;
+typedef struct elf64_symbol elf_symbol_t;
+#endif
+
+extern char *elf_error(unsigned int rc);
+
+#endif
+
+/** @}
+ */
Index: uspace/app/taskdump/include/symtab.h
===================================================================
--- uspace/app/taskdump/include/symtab.h	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
+++ uspace/app/taskdump/include/symtab.h	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2008 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup debug
+ * @{
+ */
+/** @file
+ */
+
+#ifndef SYMTAB_H_
+#define SYMTAB_H_
+
+#include <sys/types.h>
+#include <elf.h>
+
+typedef struct {
+	/** Symbol section */
+	elf_symbol_t *sym;
+	size_t sym_size;
+	/** String table */
+	char *strtab;
+	size_t strtab_size;
+} symtab_t;
+
+extern int symtab_load(const char *file_name, symtab_t **symtab);
+extern void symtab_delete(symtab_t *st);
+extern int symtab_name_to_addr(symtab_t *st, char *name, uintptr_t *addr);
+extern int symtab_addr_to_name(symtab_t *symtab, uintptr_t addr, char **name,
+    size_t *offs);
+
+#endif
+
+/** @}
+ */
Index: uspace/app/taskdump/symtab.c
===================================================================
--- uspace/app/taskdump/symtab.c	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
+++ uspace/app/taskdump/symtab.c	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
@@ -0,0 +1,373 @@
+/*
+ * Copyright (c) 2010 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup debug
+ * @{
+ */
+/** @file Handling of ELF symbol tables.
+ *
+ * This module allows one to load a symbol table from an ELF file and
+ * use it to lookup symbol names/addresses in both directions.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <elf.h>
+#include "include/symtab.h"
+
+static int elf_hdr_check(elf_header_t *hdr);
+static int section_hdr_load(int fd, const elf_header_t *ehdr, int idx,
+    elf_section_header_t *shdr);
+static int chunk_load(int fd, off_t start, off_t size, void **ptr);
+static int read_all(int fd, void *buf, size_t len);
+
+/** Load symbol table from an ELF file.
+ *
+ * @param file_name	Name of the ELF file to read from.
+ * @param symtab	Place to save pointer to new symtab structure.
+ *
+ * @return		EOK on success, ENOENT if file could not be open,
+ *			ENOTSUP if file parsing failed.
+ */
+int symtab_load(const char *file_name, symtab_t **symtab)
+{
+	symtab_t *stab;
+	elf_header_t elf_hdr;
+	elf_section_header_t sec_hdr;
+	off_t shstrt_start, shstrt_size;
+	char *shstrt, *sec_name;
+	void *data;
+
+	int fd;
+	int rc;
+	int i;
+
+	bool load_sec, sec_is_symtab;
+
+	*symtab = NULL;
+
+	stab = calloc(1, sizeof(symtab_t));
+	if (stab == NULL)
+		return ENOMEM;
+
+	fd = open(file_name, O_RDONLY);
+	if (fd < 0) {
+		printf("failed opening file\n");
+		free(stab);
+		return ENOENT;
+	}
+
+	rc = read_all(fd, &elf_hdr, sizeof(elf_header_t));
+	if (rc != EOK) {
+		printf("failed reading elf header\n");
+		free(stab);
+		return EIO;
+	}
+
+	rc = elf_hdr_check(&elf_hdr);
+	if (rc != EOK) {
+		printf("failed header check\n");
+		free(stab);
+		return ENOTSUP;
+	}
+
+	/*
+	 * Load section header string table.
+	 */
+
+	rc = section_hdr_load(fd, &elf_hdr, elf_hdr.e_shstrndx, &sec_hdr);
+	if (rc != EOK) {
+		printf("failed reading shstrt header\n");
+		free(stab);
+		return ENOTSUP;
+	}
+
+	shstrt_start = sec_hdr.sh_offset;
+	shstrt_size = sec_hdr.sh_size;
+
+	rc = chunk_load(fd, shstrt_start, shstrt_size, (void **) &shstrt);
+	if (rc != EOK) {
+		printf("failed loading shstrt\n");
+		free(stab);
+		return ENOTSUP;
+	}
+
+	/* Read all section headers. */
+	for (i = 0; i < elf_hdr.e_shnum; ++i) {
+		rc = section_hdr_load(fd, &elf_hdr, i, &sec_hdr);
+		if (rc != EOK) {
+			free(shstrt);
+			free(stab);
+			return ENOTSUP;
+		}
+
+		sec_name = shstrt + sec_hdr.sh_name;
+		if (str_cmp(sec_name, ".symtab") == 0 &&
+		    sec_hdr.sh_type == SHT_SYMTAB) {
+			load_sec = true;
+			sec_is_symtab = true;
+		} else if (str_cmp(sec_name, ".strtab") == 0 &&
+		    sec_hdr.sh_type == SHT_STRTAB) {
+			load_sec = true;
+			sec_is_symtab = false;
+		} else {
+			load_sec = false;
+		}
+
+		if (load_sec) {
+			rc = chunk_load(fd, sec_hdr.sh_offset, sec_hdr.sh_size,
+			    &data);
+			if (rc != EOK) {
+				free(shstrt);
+				free(stab);
+				return ENOTSUP;
+			}
+
+			if (sec_is_symtab) {
+				stab->sym = data;
+				stab->sym_size = sec_hdr.sh_size;
+			} else {
+				stab->strtab = data;
+				stab->strtab_size = sec_hdr.sh_size;
+			}
+		}
+	}
+
+	free(shstrt);
+	close(fd);
+
+	if (stab->sym == NULL || stab->strtab == NULL) {
+		/* Tables not found. */
+		printf("Symbol table or string table section not found\n");
+		free(stab);
+		return ENOTSUP;
+	}
+
+	*symtab = stab;
+
+	return EOK;
+}
+
+/** Delete a symtab structure.
+ *
+ * Deallocates all resources used by the symbol table.
+ */
+void symtab_delete(symtab_t *st)
+{
+	free(st->sym);
+	st->sym = NULL;
+
+	free(st->strtab);
+	st->strtab = NULL;
+
+	free(st);
+}
+
+/** Convert symbol name to address.
+ *
+ * @param st	Symbol table.
+ * @param name	Name of the symbol.
+ * @param addr	Place to store address for symbol, if found.
+ *
+ * @return	EOK on success, ENOENT if no such symbol was found.
+ */
+int symtab_name_to_addr(symtab_t *st, char *name, uintptr_t *addr)
+{
+	size_t i;
+	char *sname;
+
+	for (i = 0; i < st->sym_size / sizeof(elf_symbol_t); ++i) {
+		if (st->sym[i].st_name == 0)
+			continue;
+
+		sname = st->strtab + st->sym[i].st_name;
+
+		if (str_cmp(sname, name) == 0) {
+			*addr = st->sym[i].st_value;
+			return EOK;
+		}
+	}
+
+	return ENOENT;
+}
+
+/** Convert symbol address to name.
+ *
+ * This function finds the symbol which starts at the highest address
+ * less than or equal to @a addr.
+ *
+ * @param st	Symbol table.
+ * @param addr	Address for lookup.
+ * @param name	Place to store pointer name of symbol, if found.
+ *		This is valid while @a st exists.
+ *
+ * @return	EOK on success or ENOENT if no matching symbol was found.
+ */
+int symtab_addr_to_name(symtab_t *st, uintptr_t addr, char **name,
+    size_t *offs)
+{
+	size_t i;
+	uintptr_t saddr, best_addr;
+	char *sname, *best_name;
+
+	best_name = NULL;
+	best_addr = 0;
+
+	for (i = 0; i < st->sym_size / sizeof(elf_symbol_t); ++i) {
+		if (st->sym[i].st_name == 0)
+			continue;
+
+		saddr = st->sym[i].st_value;
+		sname = st->strtab + st->sym[i].st_name;
+
+		if (best_name == NULL || (saddr <= addr && saddr > best_addr)) {
+			best_name = sname;
+			best_addr = saddr;
+		}
+	}
+
+	if (best_name == NULL)
+		return ENOENT;
+
+	*name = best_name;
+	*offs = addr - best_addr;
+	return EOK;
+}
+
+/** Check if ELF header is valid.
+ *
+ * @return	EOK on success or negative error code.
+ */
+static int elf_hdr_check(elf_header_t *ehdr)
+{
+	/* TODO */
+	return EOK;
+}
+
+/** Load ELF section header.
+ *
+ * @param fd		File descriptor of ELF file.
+ * @param elf_hdr	Pointer to ELF file header in memory.
+ * @param idx		Index of section whose header to load (0 = first).
+ * @param sec_hdr	Place to store section header data.
+ *
+ * @return		EOK on success or EIO if I/O failed.
+ */
+static int section_hdr_load(int fd, const elf_header_t *elf_hdr, int idx,
+    elf_section_header_t *sec_hdr)
+{
+	int rc;
+
+	rc = lseek(fd, elf_hdr->e_shoff + idx * sizeof(elf_section_header_t),
+	    SEEK_SET);
+	if (rc == (off_t) -1)
+		return EIO;
+
+	rc = read_all(fd, sec_hdr, sizeof(elf_section_header_t));
+	if (rc != EOK)
+		return EIO;
+
+	return EOK;
+}
+
+/** Load a segment of bytes from a file and return it as a new memory block.
+ *
+ * This function fails if it cannot read exactly @a size bytes from the file.
+ *
+ * @param fd		File to read from.
+ * @param start		Position in file where to start reading.
+ * @param size		Number of bytes to read.
+ * @param ptr		Place to store pointer to newly allocated block.
+ *
+ * @return		EOK on success or EIO on failure.
+ */
+static int chunk_load(int fd, off_t start, off_t size, void **ptr)
+{
+	int rc;
+
+	rc = lseek(fd, start, SEEK_SET);
+	if (rc == (off_t) -1) {
+		printf("failed seeking chunk\n");
+		*ptr = NULL;
+		return EIO;
+	}
+
+	*ptr = malloc(size);
+	if (*ptr == NULL) {
+		printf("failed allocating memory\n");
+		return ENOMEM;
+	}
+
+	rc = read_all(fd, *ptr, size);
+	if (rc != EOK) {
+		printf("failed reading chunk\n");
+		free(*ptr);
+		*ptr = NULL;
+		return EIO;
+	}
+
+	return EOK;
+}
+
+/** Read until the buffer is read in its entirety.
+ *
+ * This function fails if it cannot read exactly @a len bytes from the file.
+ *
+ * @param fd		The file to read from.
+ * @param buf		Buffer for storing data, @a len bytes long.
+ * @param len		Number of bytes to read.
+ *
+ * @return		EOK on error, EIO if file is short or return value
+ *			from read() if reading failed.
+ */
+static int read_all(int fd, void *buf, size_t len)
+{
+	int cnt = 0;
+
+	do {
+		buf += cnt;
+		len -= cnt;
+		cnt = read(fd, buf, len);
+	} while (cnt > 0 && (len - cnt) > 0);
+
+	if (cnt < 0)
+		return cnt;
+
+	if (len - cnt > 0)
+		return EIO;
+
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/app/taskdump/taskdump.c
===================================================================
--- uspace/app/taskdump/taskdump.c	(revision e515b21a3fde67534b9cb58f7237e854904ccba2)
+++ uspace/app/taskdump/taskdump.c	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
@@ -46,4 +46,5 @@
 #include <bool.h>
 
+#include <symtab.h>
 #include <stacktrace.h>
 
@@ -56,4 +57,6 @@
 static task_id_t task_id;
 static bool dump_memory;
+static char *app_name;
+static symtab_t *app_symtab;
 
 static int connect_task(task_id_t task_id);
@@ -67,4 +70,8 @@
 static int td_read_uintptr(void *arg, uintptr_t addr, uintptr_t *value);
 
+static void autoload_syms(void);
+static char *get_app_task_name(void);
+static char *fmt_sym_address(uintptr_t addr);
+
 int main(int argc, char *argv[])
 {
@@ -90,5 +97,10 @@
 	}
 
-	printf("Dumping task %lld.\n\n", task_id);
+	app_name = get_app_task_name();
+	app_symtab = NULL;
+
+	printf("Dumping task '%s' (task ID %lld).\n", app_name, task_id);
+	autoload_syms();
+	putchar('\n');
 
 	rc = threads_dump();
@@ -303,4 +315,5 @@
 	uintptr_t pc, fp, nfp;
 	stacktrace_t st;
+	char *sym_pc;
 	int rc;
 
@@ -320,5 +333,7 @@
 
 	while (stacktrace_fp_valid(&st, fp)) {
-		printf("%p: %p()\n", fp, pc);
+		sym_pc = fmt_sym_address(pc);
+		printf("  %p: %s()\n", fp, sym_pc);
+		free(sym_pc);
 
 		rc = stacktrace_ra_get(&st, fp, &pc);
@@ -412,4 +427,106 @@
 }
 
+/** Attempt to find the right executable file and load the symbol table. */
+static void autoload_syms(void)
+{
+	char *file_name;
+	int rc;
+
+	assert(app_name != NULL);
+	assert(app_symtab == NULL);
+
+	rc = asprintf(&file_name, "/app/%s", app_name);
+	if (rc < 0) {
+		printf("Memory allocation failure.\n");
+		exit(1);
+	}
+
+	rc = symtab_load(file_name, &app_symtab);
+	if (rc == EOK) {
+		printf("Loaded symbol table from %s\n", file_name);
+		free(file_name);
+		return;
+	}
+
+	free(file_name);
+
+	rc = asprintf(&file_name, "/srv/%s", app_name);
+	if (rc < 0) {
+		printf("Memory allocation failure.\n");
+		exit(1);
+	}
+
+	rc = symtab_load("/srv/xyz", &app_symtab);
+	if (rc == EOK) {
+		printf("Loaded symbol table from %s\n", file_name);
+		free(file_name);
+		return;
+	}
+
+	free(file_name);
+	printf("Failed autoloading symbol table.\n");
+}
+
+static char *get_app_task_name(void)
+{
+	char dummy_buf;
+	size_t copied, needed, name_size;
+	char *name;
+	int rc;
+
+	rc = udebug_name_read(phoneid, &dummy_buf, 0, &copied, &needed);
+	if (rc < 0)
+		return NULL;
+
+	name_size = needed;
+	name = malloc(name_size + 1);
+	rc = udebug_name_read(phoneid, name, name_size, &copied, &needed);
+	if (rc < 0) {
+		free(name);
+		return NULL;
+	}
+
+	assert(copied == name_size);
+	assert(copied == needed);
+	name[copied] = '\0';
+
+	return name;
+}
+
+/** Format address in symbolic form.
+ *
+ * Formats address as <symbol_name>+<offset> (<address>), if possible,
+ * otherwise as <address>.
+ *
+ * @param addr	Address to format.
+ * @return	Newly allocated string, address in symbolic form.
+ */
+static char *fmt_sym_address(uintptr_t addr)
+{
+	char *name;
+	size_t offs;
+	int rc;
+	char *str;
+
+	if (app_symtab != NULL) {
+		rc = symtab_addr_to_name(app_symtab, addr, &name, &offs);
+	} else {
+		rc = ENOTSUP;
+	}
+
+	if (rc == EOK) {
+		rc = asprintf(&str, "(%p) %s+%p", addr, name, offs);
+	} else {
+		rc = asprintf(&str, "%p", addr);
+	}
+
+	if (rc < 0) {
+		printf("Memory allocation error.\n");
+		exit(1);
+	}
+
+	return str;
+}
+
 /** @}
  */
Index: uspace/lib/libc/arch/amd64/include/types.h
===================================================================
--- uspace/lib/libc/arch/amd64/include/types.h	(revision e515b21a3fde67534b9cb58f7237e854904ccba2)
+++ uspace/lib/libc/arch/amd64/include/types.h	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
@@ -36,4 +36,6 @@
 #define LIBC_amd64_TYPES_H_
 
+#define __64_BITS__
+
 typedef unsigned long long sysarg_t;
 
Index: uspace/lib/libc/arch/arm32/include/types.h
===================================================================
--- uspace/lib/libc/arch/arm32/include/types.h	(revision e515b21a3fde67534b9cb58f7237e854904ccba2)
+++ uspace/lib/libc/arch/arm32/include/types.h	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
@@ -37,4 +37,6 @@
 #define LIBC_arm32_TYPES_H_
 
+#define __32_BITS__
+
 typedef unsigned int sysarg_t;
 
Index: uspace/lib/libc/arch/ia32/include/types.h
===================================================================
--- uspace/lib/libc/arch/ia32/include/types.h	(revision e515b21a3fde67534b9cb58f7237e854904ccba2)
+++ uspace/lib/libc/arch/ia32/include/types.h	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
@@ -36,4 +36,6 @@
 #define LIBC_ia32_TYPES_H_
 
+#define __32_BITS__
+
 typedef unsigned int sysarg_t;
 
Index: uspace/lib/libc/arch/ia64/include/types.h
===================================================================
--- uspace/lib/libc/arch/ia64/include/types.h	(revision e515b21a3fde67534b9cb58f7237e854904ccba2)
+++ uspace/lib/libc/arch/ia64/include/types.h	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
@@ -36,4 +36,6 @@
 #define LIBC_ia64_TYPES_H_
 
+#define __64_BITS__
+
 typedef unsigned long long sysarg_t;
 
Index: uspace/lib/libc/arch/mips32/include/types.h
===================================================================
--- uspace/lib/libc/arch/mips32/include/types.h	(revision e515b21a3fde67534b9cb58f7237e854904ccba2)
+++ uspace/lib/libc/arch/mips32/include/types.h	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
@@ -37,4 +37,6 @@
 #define LIBC_mips32_TYPES_H_
 
+#define __32_BITS__
+
 typedef unsigned int sysarg_t;
 
Index: uspace/lib/libc/arch/ppc32/include/types.h
===================================================================
--- uspace/lib/libc/arch/ppc32/include/types.h	(revision e515b21a3fde67534b9cb58f7237e854904ccba2)
+++ uspace/lib/libc/arch/ppc32/include/types.h	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
@@ -36,4 +36,6 @@
 #define LIBC_ppc32_TYPES_H_
 
+#define __32_BITS__
+
 typedef unsigned int sysarg_t;
 
Index: uspace/lib/libc/arch/sparc64/include/types.h
===================================================================
--- uspace/lib/libc/arch/sparc64/include/types.h	(revision e515b21a3fde67534b9cb58f7237e854904ccba2)
+++ uspace/lib/libc/arch/sparc64/include/types.h	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
@@ -36,4 +36,6 @@
 #define LIBC_sparc64_TYPES_H_
 
+#define __64_BITS__
+
 typedef unsigned long sysarg_t;
 
Index: uspace/lib/libc/generic/udebug.c
===================================================================
--- uspace/lib/libc/generic/udebug.c	(revision e515b21a3fde67534b9cb58f7237e854904ccba2)
+++ uspace/lib/libc/generic/udebug.c	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
@@ -69,4 +69,19 @@
 }
 
+int udebug_name_read(int phoneid, void *buffer, size_t n,
+	size_t *copied, size_t *needed)
+{
+	ipcarg_t a_copied, a_needed;
+	int rc;
+
+	rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_NAME_READ,
+		(sysarg_t)buffer, n, NULL, &a_copied, &a_needed);
+
+	*copied = (size_t)a_copied;
+	*needed = (size_t)a_needed;
+
+	return rc;
+}
+
 int udebug_areas_read(int phoneid, void *buffer, size_t n,
 	size_t *copied, size_t *needed)
@@ -83,5 +98,4 @@
 	return rc;
 }
-
 
 int udebug_mem_read(int phoneid, void *buffer, uintptr_t addr, size_t n)
Index: uspace/lib/libc/include/udebug.h
===================================================================
--- uspace/lib/libc/include/udebug.h	(revision e515b21a3fde67534b9cb58f7237e854904ccba2)
+++ uspace/lib/libc/include/udebug.h	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
@@ -47,4 +47,6 @@
 int udebug_thread_read(int phoneid, void *buffer, size_t n,
 	size_t *copied, size_t *needed);
+int udebug_name_read(int phoneid, void *buffer, size_t n,
+	size_t *copied, size_t *needed);
 int udebug_areas_read(int phoneid, void *buffer, size_t n,
 	size_t *copied, size_t *needed);
Index: uspace/srv/loader/arch/amd64/Makefile.inc
===================================================================
--- uspace/srv/loader/arch/amd64/Makefile.inc	(revision e515b21a3fde67534b9cb58f7237e854904ccba2)
+++ uspace/srv/loader/arch/amd64/Makefile.inc	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
@@ -27,4 +27,3 @@
 #
 
-EXTRA_CFLAGS = -D__64_BITS__
 ARCH_SOURCES := arch/$(UARCH)/amd64.s
Index: uspace/srv/loader/arch/arm32/Makefile.inc
===================================================================
--- uspace/srv/loader/arch/arm32/Makefile.inc	(revision e515b21a3fde67534b9cb58f7237e854904ccba2)
+++ uspace/srv/loader/arch/arm32/Makefile.inc	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
@@ -27,4 +27,3 @@
 #
 
-EXTRA_CFLAGS = -D__32_BITS__
 ARCH_SOURCES := arch/$(UARCH)/arm32.s
Index: uspace/srv/loader/arch/ia32/Makefile.inc
===================================================================
--- uspace/srv/loader/arch/ia32/Makefile.inc	(revision e515b21a3fde67534b9cb58f7237e854904ccba2)
+++ uspace/srv/loader/arch/ia32/Makefile.inc	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
@@ -27,4 +27,3 @@
 #
 
-EXTRA_CFLAGS = -D__32_BITS__
 ARCH_SOURCES := arch/$(UARCH)/ia32.s
Index: uspace/srv/loader/arch/ia64/Makefile.inc
===================================================================
--- uspace/srv/loader/arch/ia64/Makefile.inc	(revision e515b21a3fde67534b9cb58f7237e854904ccba2)
+++ uspace/srv/loader/arch/ia64/Makefile.inc	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
@@ -27,5 +27,4 @@
 #
 
-EXTRA_CFLAGS = -D__64_BITS__
 ARCH_SOURCES := arch/$(UARCH)/ia64.s
 AFLAGS += -xexplicit
Index: uspace/srv/loader/arch/mips32/Makefile.inc
===================================================================
--- uspace/srv/loader/arch/mips32/Makefile.inc	(revision e515b21a3fde67534b9cb58f7237e854904ccba2)
+++ uspace/srv/loader/arch/mips32/Makefile.inc	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
@@ -27,4 +27,3 @@
 #
 
-EXTRA_CFLAGS = -D__32_BITS__
 ARCH_SOURCES := arch/$(UARCH)/mips32.s
Index: uspace/srv/loader/arch/ppc32/Makefile.inc
===================================================================
--- uspace/srv/loader/arch/ppc32/Makefile.inc	(revision e515b21a3fde67534b9cb58f7237e854904ccba2)
+++ uspace/srv/loader/arch/ppc32/Makefile.inc	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
@@ -27,4 +27,3 @@
 #
 
-EXTRA_CFLAGS = -D__32_BITS__
 ARCH_SOURCES := arch/$(UARCH)/ppc32.s
Index: uspace/srv/loader/arch/sparc64/Makefile.inc
===================================================================
--- uspace/srv/loader/arch/sparc64/Makefile.inc	(revision e515b21a3fde67534b9cb58f7237e854904ccba2)
+++ uspace/srv/loader/arch/sparc64/Makefile.inc	(revision 3698e4420e4bdd79a3251c212fbc1886ecf45436)
@@ -27,4 +27,3 @@
 #
 
-EXTRA_CFLAGS = -D__64_BITS__
 ARCH_SOURCES := arch/$(UARCH)/sparc64.s
