Commit 8782e7ca authored by Josh Poimboeuf's avatar Josh Poimboeuf Committed by Borislav Petkov
Browse files

objtool: Support Clang non-section symbols in ORC dump



Historically, the relocation symbols for ORC entries have only been
section symbols:

  .text+0: sp:sp+8 bp:(und) type:call end:0

However, the Clang assembler is aggressive about stripping section
symbols.  In that case we will need to use function symbols:

  freezing_slow_path+0: sp:sp+8 bp:(und) type:call end:0

In preparation for the generation of such entries in "objtool orc
generate", add support for reading them in "objtool orc dump".

Signed-off-by: default avatarJosh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Reviewed-by: default avatarMiroslav Benes <mbenes@suse.cz>
Acked-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/b811b5eb1a42602c3b523576dc5efab9ad1c174d.1585761021.git.jpoimboe@redhat.com
parent bd841d61
Loading
Loading
Loading
Loading
+27 −17
Original line number Diff line number Diff line
@@ -66,7 +66,7 @@ int orc_dump(const char *_objname)
	char *name;
	size_t nr_sections;
	Elf64_Addr orc_ip_addr = 0;
	size_t shstrtab_idx;
	size_t shstrtab_idx, strtab_idx = 0;
	Elf *elf;
	Elf_Scn *scn;
	GElf_Shdr sh;
@@ -127,6 +127,8 @@ int orc_dump(const char *_objname)

		if (!strcmp(name, ".symtab")) {
			symtab = data;
		} else if (!strcmp(name, ".strtab")) {
			strtab_idx = i;
		} else if (!strcmp(name, ".orc_unwind")) {
			orc = data->d_buf;
			orc_size = sh.sh_size;
@@ -138,7 +140,7 @@ int orc_dump(const char *_objname)
		}
	}

	if (!symtab || !orc || !orc_ip)
	if (!symtab || !strtab_idx || !orc || !orc_ip)
		return 0;

	if (orc_size % sizeof(*orc) != 0) {
@@ -159,6 +161,7 @@ int orc_dump(const char *_objname)
				return -1;
			}

			if (GELF_ST_TYPE(sym.st_info) == STT_SECTION) {
				scn = elf_getscn(elf, sym.st_shndx);
				if (!scn) {
					WARN_ELF("elf_getscn");
@@ -171,10 +174,17 @@ int orc_dump(const char *_objname)
				}

				name = elf_strptr(elf, shstrtab_idx, sh.sh_name);
			if (!name || !*name) {
				if (!name) {
					WARN_ELF("elf_strptr");
					return -1;
				}
			} else {
				name = elf_strptr(elf, strtab_idx, sym.st_name);
				if (!name) {
					WARN_ELF("elf_strptr");
					return -1;
				}
			}

			printf("%s+%llx:", name, (unsigned long long)rela.r_addend);