summaryrefslogtreecommitdiff
path: root/mld/obj.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--mld/obj.c103
1 files changed, 90 insertions, 13 deletions
diff --git a/mld/obj.c b/mld/obj.c
index b065316..e986a75 100644
--- a/mld/obj.c
+++ b/mld/obj.c
@@ -49,10 +49,10 @@ static int load_ehdr(struct object *object)
EHDR_ASSERT(type, sizeof(Elf32_Half));
EHDR_ASSERT(machine, sizeof(Elf32_Half));
EHDR_ASSERT(version, sizeof(Elf32_Word));
- EHDR_ASSERT(flags, sizeof(Elf32_Word));
+ // EHDR_ASSERT(flags, sizeof(Elf32_Word));
EHDR_ASSERT(ehsize, sizeof(Elf32_Half));
- EHDR_ASSERT(phentsize, sizeof(Elf32_Half));
- EHDR_ASSERT(shentsize, sizeof(Elf32_Half));
+ // EHDR_ASSERT(phentsize, sizeof(Elf32_Half));
+ // EHDR_ASSERT(shentsize, sizeof(Elf32_Half));
#undef EHDR_ASSERT
@@ -82,25 +82,96 @@ static int load_shdr(struct object *object)
}
/**
- * Map the phdr
+ * Create the phdr
*/
-static int load_phdr(struct object *object)
+static int create_phdr(struct object *object)
{
- size_t phdr_len = B16(object->ehdr->e_phentsize) *
- B16(object->ehdr->e_phnum);
- size_t phdr_off = B32(object->ehdr->e_phoff);
- object->phdr = (Elf32_Phdr *) (object->mapped + phdr_off);
- object->phdr_len = B16(object->ehdr->e_phnum);
+ uint32_t entries = 0;
+ for (uint32_t i = 0; i < object->shdr_len; i++) {
+ Elf32_Shdr *hdr = &object->shdr[i];
+ uint32_t type = B32(hdr->sh_type);
+
+ if (type != SHT_PROGBITS && type != SHT_NOBITS)
+ continue;
+
+ entries += 1;
+ }
- if (BOUND_CHK(object, phdr_len, phdr_off)) {
- ERROR("cannot read phdr");
+ Elf32_Phdr *phdr = malloc(entries * sizeof(Elf32_Phdr));
+ if (phdr == NULL) {
+ PERROR("cannot alloc");
return M_ERROR;
}
+ object->phdr = phdr;
+ object->phdr_len = entries;
+ object->phdr_local = true;
+
+ uint32_t *mapping = malloc(entries * sizeof(uint32_t));
+ if (mapping == NULL) {
+ PERROR("cannot alloc");
+ return M_ERROR;
+ }
+
+ object->phdr_to_shdr_mapping = mapping;
+
+ uint32_t index = 0;
+ for (uint32_t i = 0; i < object->shdr_len; i++) {
+ Elf32_Shdr *hdr = &object->shdr[i];
+ uint32_t type = B32(hdr->sh_type);
+
+ if (type != SHT_PROGBITS && type != SHT_NOBITS)
+ continue;
+ mapping[index] = i;
+ phdr[index++] = (Elf32_Phdr) {
+ .p_type = B32(PT_LOAD),
+ .p_flags = B32(
+ // execute
+ ((B32(hdr->sh_flags) & SHF_EXECINSTR)
+ ? PF_X : 0) |
+ // write
+ ((B32(hdr->sh_flags) & SHF_WRITE)
+ ? PF_W : 0) |
+ // read
+ ((B32(hdr->sh_flags) & SHF_ALLOC)
+ ? PF_R : 0)
+ ),
+ .p_offset = hdr->sh_offset,
+ .p_vaddr = hdr->sh_addr,
+ .p_paddr = hdr->sh_addr,
+ .p_filesz = hdr->sh_size,
+ .p_memsz = hdr->sh_size,
+ .p_align = B32(SEC_ALIGN),
+ };
+ }
+
return M_SUCCESS;
}
/**
+ * Map the phdr
+ */
+static int load_phdr(struct object *object)
+{
+ //size_t phdr_len = B16(object->ehdr->e_phentsize) *
+ // B16(object->ehdr->e_phnum);
+
+ //if (phdr_len < 1)
+ return create_phdr(object);
+
+ //size_t phdr_off = B32(object->ehdr->e_phoff);
+ //object->phdr = (Elf32_Phdr *) (object->mapped + phdr_off);
+ //object->phdr_len = B16(object->ehdr->e_phnum);
+
+ //if (BOUND_CHK(object, phdr_len, phdr_off)) {
+ // ERROR("cannot read phdr");
+ // return M_ERROR;
+ //}
+
+ //return M_SUCCESS;
+}
+
+/**
* Load the strtabs
*/
static int load_strtabs(struct object *object)
@@ -231,7 +302,7 @@ static int load_shstrtab(struct object *object)
*/
static int load_segments(struct object *object)
{
- object->segment_len = B16(object->ehdr->e_phnum);
+ object->segment_len = object->phdr_len;
object->segments = malloc(sizeof(struct segment) *
object->segment_len);
@@ -287,6 +358,8 @@ int object_load(struct object *object, char *path, uint32_t index)
object->mapped = NULL;
object->name = path;
object->index = index;
+ object->phdr_local = false;
+ object->phdr_to_shdr_mapping = NULL;
/** load the file */
if (map_file(object, path))
@@ -331,6 +404,10 @@ void object_free(struct object *obj)
free(obj->strtabs);
if (obj->segments != NULL)
free(obj->segments);
+ if (obj->phdr_local)
+ free(obj->phdr);
+ if (obj->phdr_to_shdr_mapping)
+ free(obj->phdr_to_shdr_mapping);
if (obj->fd > 0)
close(obj->fd);
if (obj->mapped != NULL && obj->mapped != MAP_FAILED)