diff --git a/core/arch/arm/kernel/user_ta.c b/core/arch/arm/kernel/user_ta.c index 2e4cbbca608..03b87b618ec 100644 --- a/core/arch/arm/kernel/user_ta.c +++ b/core/arch/arm/kernel/user_ta.c @@ -501,6 +501,7 @@ static void user_ta_enter_close_session(struct tee_ta_session *s) static void user_ta_dump_state(struct tee_ta_ctx *ctx) { struct user_ta_ctx *utc __maybe_unused = to_user_ta_ctx(ctx); + char flags[4] = { '\0', }; size_t n; EMSG_RAW(" arch: %s load address: 0x%x ctx-idr: %d", @@ -515,10 +516,12 @@ static void user_ta_dump_state(struct tee_ta_ctx *ctx) mobj_get_pa(utc->mmu->regions[n].mobj, utc->mmu->regions[n].offset, 0, &pa); + mattr_uflags_to_str(flags, sizeof(flags), + utc->mmu->regions[n].attr); EMSG_RAW(" region %zu: va %#" PRIxVA " pa %#" PRIxPA - " size %#zx", + " size %#zx flags %s", n, utc->mmu->regions[n].va, pa, - utc->mmu->regions[n].size); + utc->mmu->regions[n].size, flags); } } KEEP_PAGER(user_ta_dump_state); diff --git a/core/include/mm/tee_mmu_types.h b/core/include/mm/tee_mmu_types.h index 891f2544ac0..855136bfd28 100644 --- a/core/include/mm/tee_mmu_types.h +++ b/core/include/mm/tee_mmu_types.h @@ -89,4 +89,15 @@ struct tee_mmu_info { vaddr_t ta_private_vmem_end; }; +static inline void mattr_uflags_to_str(char *str, size_t size, uint32_t attr) +{ + if (size < 4) + return; + + str[0] = (attr & TEE_MATTR_UR) ? 'r' : '-'; + str[1] = (attr & TEE_MATTR_UW) ? 'w' : '-'; + str[2] = (attr & TEE_MATTR_UX) ? 'x' : '-'; + str[3] = '\0'; +} + #endif diff --git a/scripts/symbolize.py b/scripts/symbolize.py index 9599b6f8528..772ba2e68b0 100755 --- a/scripts/symbolize.py +++ b/scripts/symbolize.py @@ -40,6 +40,8 @@ CALL_STACK_RE = re.compile('Call stack:') STACK_ADDR_RE = re.compile(r': (?P0x[0-9a-f]+)') ABORT_ADDR_RE = re.compile('-abort at address (?P0x[0-9a-f]+)') +REGION_RE = re.compile('region [0-9]+: va (?P0x[0-9a-f]+) ' + 'pa 0x[0-9a-f]+ size (?P0x[0-9a-f]+)') epilog = ''' This scripts reads an OP-TEE abort message from stdin and adds debug @@ -157,7 +159,7 @@ def symbol_plus_offset(self, addr): cmd = self.arch_prefix('nm') if not reladdr or not elf or not cmd: return '' - ireladdr = int(reladdr, 0) + ireladdr = int(reladdr, 16) nm = subprocess.Popen([cmd, '--numeric-sort', '--print-size', elf], stdin = subprocess.PIPE, stdout = subprocess.PIPE) @@ -193,7 +195,7 @@ def section_plus_offset(self, addr): cmd = self.arch_prefix('objdump') if not reladdr or not elf or not cmd: return '' - iaddr = int(reladdr, 0) + iaddr = int(reladdr, 16) objdump = subprocess.Popen([cmd, '--section-headers', elf], stdin = subprocess.PIPE, stdout = subprocess.PIPE) @@ -232,6 +234,44 @@ def process_abort(self, line): ret += line[post:] return ret + # Return all ELF sections with the ALLOC flag + def read_sections(self): + if self._sections: + return + elf = self.get_elf(self._bin) + cmd = self.arch_prefix('objdump') + if not elf or not cmd: + return + objdump = subprocess.Popen([cmd, '--section-headers', elf], + stdin = subprocess.PIPE, + stdout = subprocess.PIPE) + for line in iter(objdump.stdout.readline, ''): + try: + _, name, size, vma, _, _, _ = line.split() + except: + if 'ALLOC' in line: + self._sections.append([name, int(vma, 16), int(size, 16)]) + + def overlaps(self, section, addr, size): + sec_addr = section[1] + sec_size = section[2] + if not size or not sec_size: + return False + return (addr <= (sec_addr + sec_size - 1)) and ((addr + size - 1) >= sec_addr) + + def sections_in_region(self, addr, size): + ret = '' + addr = self.subtract_load_addr(addr) + if not addr: + return '' + iaddr = int(addr, 16) + isize = int(size, 16) + self.read_sections() + for s in self._sections: + if self.overlaps(s, iaddr, isize): + ret += ' ' + s[0] + return ret + def reset(self): self._call_stack_found = False self._load_addr = '0' @@ -240,6 +280,7 @@ def reset(self): self._addr2line = None self._arch = None self._saved_abort_line = '' + self._sections = [] def write(self, line): if self._call_stack_found: @@ -259,6 +300,13 @@ def write(self, line): return else: self.reset() + match = re.search(REGION_RE, line) + if match: + addr = match.group('addr') + size = match.group('size') + self._out.write(line.strip() + + self.sections_in_region(addr, size) + '\n'); + return match = re.search(CALL_STACK_RE, line) if match: self._call_stack_found = True