diff options
Diffstat (limited to 'mld/seg.c')
-rw-r--r-- | mld/seg.c | 50 |
1 files changed, 18 insertions, 32 deletions
@@ -25,44 +25,30 @@ static int load_phdr(struct object *obj, struct segment *seg, size_t index) */ static int load_shdr(struct object *obj, struct segment *seg, size_t index) { - bool found = false; + uint32_t shndx = obj->phdr_to_shdr_mapping[index]; + Elf32_Shdr *hdr = &obj->shdr[shndx]; - for (size_t i = 0; i < obj->shdr_len; i++) { - Elf32_Shdr *hdr = &obj->shdr[i]; - - // find shdr that matches the offset in phdr - if (!PHDR_SHDR_MATCH(seg->phdr, hdr)) - continue; - - // get name - uint32_t name = B32(hdr->sh_name); - if (name >= obj->shstrtab->len) { - ERROR("section name index [%d] out of bounds", name); - return M_ERROR; - } - seg->name = &obj->shstrtab->data[name]; - - // map bytes - uint32_t len = B32(hdr->sh_size); - uint32_t off = B32(hdr->sh_offset); - seg->bytes = (unsigned char *) (obj->mapped + off); - - if (BOUND_CHK(obj, len, off)) { - ERROR("cannot map seg %s:%d", seg->name, index); - return M_ERROR; - } - - found = true; - seg->shdr = hdr; - seg->shdr_idx = i; - break; + // get name + uint32_t name = B32(hdr->sh_name); + if (name >= obj->shstrtab->len) { + ERROR("section name index [%d] out of bounds", name); + return M_ERROR; } + seg->name = &obj->shstrtab->data[name]; - if (!found) { - ERROR("cannot find shdr for segment [%d]", index); + // map bytes + uint32_t len = B32(hdr->sh_size); + uint32_t off = B32(hdr->sh_offset); + seg->bytes = (unsigned char *) (obj->mapped + off); + + if (BOUND_CHK(obj, len, off)) { + ERROR("cannot map seg %s:%d", seg->name, index); return M_ERROR; } + seg->shdr = hdr; + seg->shdr_idx = shndx; + return M_SUCCESS; } |