⛏️ index : haiku.git

author Axel Dörfler <axeld@pinc-software.de> 2004-05-31 20:30:20.0 +00:00:00
committer Axel Dörfler <axeld@pinc-software.de> 2004-05-31 20:30:20.0 +00:00:00
commit
fa1ddc4f0e6829a28be436efe89dd4c0c9018dcc [patch]
tree
bf28b1d077f7cd1e4da6e29fef47e0ec8e6aec80
parent
499683d565c47c000a74b8f637d9697f80d86845
download
fa1ddc4f0e6829a28be436efe89dd4c0c9018dcc.tar.gz

For debugging purposes, the boot loader is now able to load an additional symbol table into memory and hand it over to the kernel.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7695 a95241bf-73f2-0310-859d-f6bbb57e9c96

Diff

 headers/private/kernel/boot/elf.h |   4 ++++
 src/kernel/boot/loader/elf.cpp    | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 114 insertions(+), 2 deletions(-)

diff --git a/headers/private/kernel/boot/elf.h b/headers/private/kernel/boot/elf.h
index 8d83020..f3b80cc 100644
--- a/headers/private/kernel/boot/elf.h
+++ b/headers/private/kernel/boot/elf.h
@@ -18,6 +18,10 @@
	addr_range	dynamic_section;
	struct Elf32_Ehdr elf_header;

	struct Elf32_Sym *debug_symbols;
	const char	*debug_string_table;
	uint32		num_debug_symbols, debug_string_table_size;

	image_id	id;
		// the ID field will be filled out in the kernel
};
diff --git a/src/kernel/boot/loader/elf.cpp b/src/kernel/boot/loader/elf.cpp
index 3d1fc3f..ce9605f 100644
--- a/src/kernel/boot/loader/elf.cpp
+++ b/src/kernel/boot/loader/elf.cpp
@@ -37,6 +37,106 @@
}


static status_t
load_elf_symbol_table(int fd, preloaded_image *image)
{
	struct Elf32_Ehdr &elfHeader = image->elf_header;
	Elf32_Sym *symbolTable = NULL;
	Elf32_Shdr *stringHeader = NULL;
	uint32 numSymbols = 0;
	char *stringTable;
	status_t status;

	// get section headers

	ssize_t size = elfHeader.e_shnum * elfHeader.e_shentsize;
	Elf32_Shdr *sectionHeaders = (struct Elf32_Shdr *)malloc(size);
	if (sectionHeaders == NULL) {
		dprintf("error allocating space for section headers\n");
		return B_NO_MEMORY;
	}

	ssize_t length = read_pos(fd, elfHeader.e_shoff, sectionHeaders, size);
	if (length < size) {
		TRACE(("error reading in program headers\n"));
		status = B_ERROR;
		goto error1;
	}
	
	// find symbol table in section headers
	
	for (int32 i = 0; i < elfHeader.e_shnum; i++) {
		if (sectionHeaders[i].sh_type == SHT_SYMTAB) {
			stringHeader = &sectionHeaders[sectionHeaders[i].sh_link];

			if (stringHeader->sh_type != SHT_STRTAB) {
				TRACE(("doesn't link to string table\n"));
				status = B_BAD_DATA;
				goto error1;
			}

			// read in symbol table
			symbolTable = (Elf32_Sym *)kernel_args_malloc(size = sectionHeaders[i].sh_size);
			if (symbolTable == NULL) {
				status = B_NO_MEMORY;
				goto error1;
			}

			length = read_pos(fd, sectionHeaders[i].sh_offset, symbolTable, size);
			if (length < size) {
				TRACE(("error reading in symbol table\n"));
				status = B_ERROR;
				goto error1;
			}

			numSymbols = size / sizeof(Elf32_Sym);
			break;
		}
	}

	if (symbolTable == NULL) {
		TRACE(("no symbol table\n"));
		status = B_BAD_VALUE;
		goto error1;
	}

	// read in string table

	stringTable = (char *)kernel_args_malloc(size = stringHeader->sh_size);
	if (stringTable == NULL) {
		status = B_NO_MEMORY;
		goto error2;
	}

	length = read_pos(fd, stringHeader->sh_offset, stringTable, size);
	if (length < size) {
		TRACE(("error reading in string table\n"));
		status = B_ERROR;
		goto error3;
	}

	TRACE(("loaded debug %ld symbols\n", numSymbols));

	// insert tables into image
	image->debug_symbols = symbolTable;
	image->num_debug_symbols = numSymbols;
	image->debug_string_table = stringTable;
	image->debug_string_table_size = size;

	free(sectionHeaders);
	return B_OK;

error3:
	kernel_args_free(stringTable);
error2:
	kernel_args_free(symbolTable);
error1:
	free(sectionHeaders);

	return status;
}


status_t
elf_load_image(int fd, preloaded_image *image)
{
@@ -74,7 +174,7 @@
	image->data_region.size = 0;
	image->text_region.size = 0;

	for (int i = 0; i < elfHeader.e_phnum; i++) {
	for (int32 i = 0; i < elfHeader.e_phnum; i++) {
		switch (programHeaders[i].p_type) {
			case PT_LOAD:
				break;
@@ -141,7 +241,7 @@
		else
			continue;

		TRACE(("load segment %d...\n", i));
		TRACE(("load segment %d (%ld bytes)...\n", i, programHeaders[i].p_filesz));

		length = read_pos(fd, programHeaders[i].p_offset,
			(void *)(region->start + (programHeaders[i].p_vaddr % B_PAGE_SIZE)),
@@ -155,6 +255,14 @@

	// modify the dynamic section by the delta of the regions
	image->dynamic_section.start += image->text_region.delta;

	image->num_debug_symbols = 0;
	image->debug_symbols = NULL;
	image->debug_string_table = NULL;

	// ToDo: this should be enabled by kernel settings!
	if (1)
		load_elf_symbol_table(fd, image);

	free(programHeaders);