Bug 568451 - BaseAddress for the MemoryMap
diff --git a/agent/tcf/services/tcf_elf.c b/agent/tcf/services/tcf_elf.c
index 30918c3..ce73c47 100644
--- a/agent/tcf/services/tcf_elf.c
+++ b/agent/tcf/services/tcf_elf.c
@@ -1276,26 +1276,28 @@
return r;
}
-static void program_headers_ranges(ELF_File * file, ContextAddress addr0, ContextAddress addr1, MemoryMap * res) {
+static void program_headers_ranges(ELF_File * file, ContextAddress addr0, ContextAddress addr1, MemoryMap * res, ContextAddress base_addr) {
unsigned j;
for (j = 0; j < file->pheader_cnt; j++) {
ELF_PHeader * p = file->pheaders + j;
- if (p->mem_size == 0) continue;
- if (p->type != PT_LOAD) continue;
- if (p->address <= addr1 && p->address + p->mem_size - 1 >= addr0) {
- MemoryRegion * x = add_region(res);
- x->addr = (ContextAddress)p->address;
- x->size = (ContextAddress)p->mem_size;
- x->dev = file->dev;
- x->ino = file->ino;
- x->file_name = file->name;
- x->file_offs = p->offset;
- x->file_size = p->file_size;
- x->bss = p->file_size == 0 && p->mem_size != 0;
- if (p->flags & PF_R) x->flags |= MM_FLAG_R;
- if (p->flags & PF_W) x->flags |= MM_FLAG_W;
- if (p->flags & PF_X) x->flags |= MM_FLAG_X;
- x->valid = MM_VALID_ADDR | MM_VALID_SIZE | MM_VALID_FILE_OFFS | MM_VALID_FILE_SIZE;
+ if (p->type == PT_LOAD && p->mem_size > 0) {
+ ContextAddress p_addr0 = (ContextAddress)p->address + base_addr;
+ ContextAddress p_addr1 = (ContextAddress)(p->address + p->mem_size - 1) + base_addr;
+ if (p_addr0 <= addr1 && p_addr1 >= addr0) {
+ MemoryRegion * x = add_region(res);
+ x->addr = p_addr0;
+ x->size = (ContextAddress)p->mem_size;
+ x->dev = file->dev;
+ x->ino = file->ino;
+ x->file_name = file->name;
+ x->file_offs = p->offset;
+ x->file_size = p->file_size;
+ x->bss = p->file_size == 0 && p->mem_size != 0;
+ if (p->flags & PF_R) x->flags |= MM_FLAG_R;
+ if (p->flags & PF_W) x->flags |= MM_FLAG_W;
+ if (p->flags & PF_X) x->flags |= MM_FLAG_X;
+ x->valid = MM_VALID_ADDR | MM_VALID_SIZE | MM_VALID_FILE_OFFS | MM_VALID_FILE_SIZE;
+ }
}
}
}
@@ -1419,26 +1421,29 @@
if (no_addr && no_size && no_file_offs && no_file_size && r->sect_name == NULL) {
ELF_File * file = elf_open_memory_region_file(r, NULL);
if (file != NULL) {
+ ContextAddress base_addr = 0;
KernelModuleAddress * module = NULL;
- if (r->attrs != NULL) {
- MemoryRegionAttribute * a = r->attrs;
- while (a != NULL) {
- if (strcmp(a->name, "KernelModule") == 0) {
- ByteArrayInputStream buf;
- InputStream * inp = create_byte_array_input_stream(&buf, a->value, strlen(a->value));
- module = (KernelModuleAddress *)tmp_alloc_zero(sizeof(KernelModuleAddress));
- json_read_struct(inp, read_module_struct, module);
- json_test_char(inp, MARKER_EOS);
- break;
- }
- a = a->next;
+ MemoryRegionAttribute * a = r->attrs;
+ while (a != NULL) {
+ ByteArrayInputStream buf;
+ if (strcmp(a->name, "KernelModule") == 0) {
+ InputStream * inp = create_byte_array_input_stream(&buf, a->value, strlen(a->value));
+ module = (KernelModuleAddress *)tmp_alloc_zero(sizeof(KernelModuleAddress));
+ json_read_struct(inp, read_module_struct, module);
+ json_test_char(inp, MARKER_EOS);
}
+ else if (strcmp(a->name, "BaseAddress") == 0) {
+ InputStream * inp = create_byte_array_input_stream(&buf, a->value, strlen(a->value));
+ base_addr = (ContextAddress)json_read_uint64(inp);
+ json_test_char(inp, MARKER_EOS);
+ }
+ a = a->next;
}
if (module != NULL) {
linux_kernel_module_ranges(file, module, addr0, addr1, res);
}
else {
- program_headers_ranges(file, addr0, addr1, res);
+ program_headers_ranges(file, addr0, addr1, res, base_addr);
}
}
}
@@ -1460,25 +1465,7 @@
if (p->offset == 0) break;
}
}
- for (j = 0; j < file->pheader_cnt; j++) {
- ELF_PHeader * p = file->pheaders + j;
- if (p->type == PT_LOAD && p->mem_size > 0) {
- ContextAddress p_addr0 = (ContextAddress)p->address + base_addr;
- ContextAddress p_addr1 = (ContextAddress)(p->address + p->mem_size - 1) + base_addr;
- if (p_addr0 <= addr1 && p_addr1 >= addr0) {
- MemoryRegion * x = add_region(res);
- x->addr = p_addr0;
- x->size = (ContextAddress)p->mem_size;
- x->dev = file->dev;
- x->ino = file->ino;
- x->file_name = file->name;
- x->file_offs = p->offset;
- x->file_size = p->file_size;
- x->flags = MM_FLAG_R | MM_FLAG_W | MM_FLAG_X;
- x->valid = MM_VALID_ADDR | MM_VALID_SIZE | MM_VALID_FILE_OFFS | MM_VALID_FILE_SIZE;
- }
- }
- }
+ program_headers_ranges(file, addr0, addr1, res, base_addr);
}
}
}