lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <ebf2286ed0aeb66c61501c9df935b1193eeeb702.1725334260.git.jpoimboe@kernel.org>
Date: Mon,  2 Sep 2024 21:00:00 -0700
From: Josh Poimboeuf <jpoimboe@...nel.org>
To: live-patching@...r.kernel.org
Cc: linux-kernel@...r.kernel.org,
	x86@...nel.org,
	Miroslav Benes <mbenes@...e.cz>,
	Petr Mladek <pmladek@...e.com>,
	Joe Lawrence <joe.lawrence@...hat.com>,
	Jiri Kosina <jikos@...nel.org>,
	Peter Zijlstra <peterz@...radead.org>,
	Marcos Paulo de Souza <mpdesouza@...e.com>,
	Song Liu <song@...nel.org>
Subject: [RFC 17/31] objtool: Open up the elf API

Expose more functionality in the ELF library.  This will be needed for
the upcoming "objtool klp" support.

Signed-off-by: Josh Poimboeuf <jpoimboe@...nel.org>
---
 tools/objtool/elf.c                 | 338 +++++++++++++++++++---------
 tools/objtool/include/objtool/elf.h |  30 ++-
 tools/objtool/orc_gen.c             |   6 +-
 3 files changed, 260 insertions(+), 114 deletions(-)

diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index 84cb6fc235c9..0c95d7cdf0f5 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -18,10 +18,11 @@
 #include <errno.h>
 #include <linux/interval_tree_generic.h>
 #include <objtool/builtin.h>
-
 #include <objtool/elf.h>
 #include <objtool/warn.h>
 
+#define ALIGN_UP(x, align_to) (((x) + ((align_to)-1)) & ~((align_to)-1))
+
 static inline u32 str_hash(const char *str)
 {
 	return jhash(str, strlen(str), 0);
@@ -261,6 +262,18 @@ struct symbol *find_symbol_by_name(const struct elf *elf, const char *name)
 	return NULL;
 }
 
+struct symbol *find_global_symbol_by_name(const struct elf *elf, const char *name)
+{
+	struct symbol *sym;
+
+	elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash(name)) {
+		if (!strcmp(sym->name, name) && !is_local_symbol(sym))
+			return sym;
+	}
+
+	return NULL;
+}
+
 struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec,
 				     unsigned long offset, unsigned int len)
 {
@@ -549,7 +562,7 @@ static void elf_update_sym_relocs(struct elf *elf, struct symbol *sym)
 static void elf_update_symbol(struct elf *elf, struct section *symtab,
 			     struct section *symtab_shndx, struct symbol *sym)
 {
-	Elf32_Word shndx = sym->sec ? sym->sec->idx : SHN_UNDEF;
+	Elf32_Word shndx;
 	Elf_Data *symtab_data = NULL, *shndx_data = NULL;
 	Elf64_Xword entsize = symtab->sh.sh_entsize;
 	int max_idx, idx = sym->idx;
@@ -557,8 +570,7 @@ static void elf_update_symbol(struct elf *elf, struct section *symtab,
 	bool is_special_shndx = sym->sym.st_shndx >= SHN_LORESERVE &&
 				sym->sym.st_shndx != SHN_XINDEX;
 
-	if (is_special_shndx)
-		shndx = sym->sym.st_shndx;
+	shndx = is_special_shndx ? sym->sym.st_shndx : sym->sec->idx;
 
 	s = elf_getscn(elf->elf, symtab->idx);
 	if (!s)
@@ -654,12 +666,29 @@ static void elf_update_symbol(struct elf *elf, struct section *symtab,
 		ERROR_ELF("gelf_update_symshndx");
 }
 
-static struct symbol *
-__elf_create_symbol(struct elf *elf, struct symbol *sym)
+static struct symbol *__elf_create_symbol(struct elf *elf, const char *name,
+					  struct section *sec, unsigned int bind,
+					  unsigned int type, unsigned long offset,
+					  size_t size)
 {
 	struct section *symtab, *symtab_shndx;
 	Elf32_Word first_non_local, new_idx;
-	struct symbol *old;
+	struct symbol *old, *sym;
+
+	sym = calloc(1, sizeof(*sym));
+	ERROR_ON(!sym, "calloc");
+
+	if (name) {
+		sym->name = strdup(name);
+		if (type != STT_SECTION)
+			sym->sym.st_name = elf_add_string(elf, NULL, sym->name);
+	}
+
+	sym->sec = sec ? : find_section_by_index(elf, 0);
+
+	sym->sym.st_info  = GELF_ST_INFO(bind, type);
+	sym->sym.st_value = offset;
+	sym->sym.st_size  = size;
 
 	symtab = find_section_by_name(elf, ".symtab");
 	if (!symtab)
@@ -669,7 +698,7 @@ __elf_create_symbol(struct elf *elf, struct symbol *sym)
 
 	new_idx = sec_num_entries(symtab);
 
-	if (GELF_ST_BIND(sym->sym.st_info) != STB_LOCAL)
+	if (bind != STB_LOCAL)
 		goto non_local;
 
 	/*
@@ -698,7 +727,8 @@ __elf_create_symbol(struct elf *elf, struct symbol *sym)
 
 non_local:
 	sym->idx = new_idx;
-	elf_update_symbol(elf, symtab, symtab_shndx, sym);
+	if (sym->idx)
+		elf_update_symbol(elf, symtab, symtab_shndx, sym);
 
 	symtab->sh.sh_size += symtab->sh.sh_entsize;
 	mark_sec_changed(elf, symtab, true);
@@ -708,63 +738,49 @@ __elf_create_symbol(struct elf *elf, struct symbol *sym)
 		mark_sec_changed(elf, symtab_shndx, true);
 	}
 
+	elf_add_symbol(elf, sym);
+
 	return sym;
 }
 
-static struct symbol *
-elf_create_section_symbol(struct elf *elf, struct section *sec)
+struct symbol *elf_create_symbol(struct elf *elf, const char *name,
+				   struct section *sec, unsigned int bind,
+				   unsigned int type, unsigned long offset,
+				   size_t size)
+{
+	return __elf_create_symbol(elf, name, sec, bind, type, offset, size);
+}
+
+struct symbol *elf_create_section_symbol(struct elf *elf, struct section *sec)
 {
 	struct symbol *sym;
 
-	sym = calloc(1, sizeof(*sym));
-	ERROR_ON(!sym, "calloc");
-
-	sym->name = sec->name;
-	sym->sec = sec;
-
-	// st_name 0
-	sym->sym.st_info = GELF_ST_INFO(STB_LOCAL, STT_SECTION);
-	// st_other 0
-	// st_value 0
-	// st_size 0
-
-	sym = __elf_create_symbol(elf, sym);
-	elf_add_symbol(elf, sym);
+	sym = elf_create_symbol(elf, sec->name, sec, STB_LOCAL, STT_SECTION, 0, 0);
+	sec->sym = sym;
 
 	return sym;
 }
 
-static int elf_add_string(struct elf *elf, struct section *strtab, const char *str);
-
 struct symbol *
-elf_create_prefix_symbol(struct elf *elf, struct symbol *orig, long size)
+elf_create_prefix_symbol(struct elf *elf, struct symbol *orig, size_t size)
 {
-	struct symbol *sym = calloc(1, sizeof(*sym));
 	size_t namelen = strlen(orig->name) + sizeof("__pfx_");
-	char *name = malloc(namelen);
-
-	ERROR_ON(!sym || !name, "malloc");
+	char name[SYM_NAME_LEN];
+	unsigned long offset;
 
 	snprintf(name, namelen, "__pfx_%s", orig->name);
 
-	sym->name = name;
-	sym->sec = orig->sec;
+	offset = orig->sym.st_value - size;
 
-	sym->sym.st_name = elf_add_string(elf, NULL, name);
-	sym->sym.st_info = orig->sym.st_info;
-	sym->sym.st_value = orig->sym.st_value - size;
-	sym->sym.st_size = size;
-
-	sym = __elf_create_symbol(elf, sym);
-	elf_add_symbol(elf, sym);
-
-	return sym;
+	return elf_create_symbol(elf, name, orig->sec,
+				 GELF_ST_BIND(orig->sym.st_info),
+				 GELF_ST_TYPE(orig->sym.st_info),
+				 offset, size);
 }
 
-static struct reloc *elf_init_reloc(struct elf *elf, struct section *rsec,
-				    unsigned int reloc_idx,
-				    unsigned long offset, struct symbol *sym,
-				    s64 addend, unsigned int type)
+struct reloc *elf_init_reloc(struct elf *elf, struct section *rsec,
+			     unsigned int reloc_idx, unsigned long offset,
+			     struct symbol *sym, s64 addend, unsigned int type)
 {
 	struct reloc *reloc, empty = { 0 };
 
@@ -800,7 +816,7 @@ struct reloc *elf_init_reloc_text_sym(struct elf *elf, struct section *sec,
 				    unsigned long insn_off)
 {
 	struct symbol *sym = insn_sec->sym;
-	int addend = insn_off;
+	s64 addend = insn_off;
 
 	if (!is_text_section(insn_sec))
 		ERROR("bad call to %s() for data symbol %s", __func__, sym->name);
@@ -813,8 +829,6 @@ struct reloc *elf_init_reloc_text_sym(struct elf *elf, struct section *sec,
 		 * non-weak function after linking.
 		 */
 		sym = elf_create_section_symbol(elf, insn_sec);
-
-		insn_sec->sym = sym;
 	}
 
 	return elf_init_reloc(elf, sec->rsec, reloc_idx, offset, sym, addend,
@@ -926,11 +940,9 @@ struct elf *elf_open_read(const char *name, int flags)
 	return elf;
 }
 
-static int elf_add_string(struct elf *elf, struct section *strtab, const char *str)
+unsigned long elf_add_string(struct elf *elf, struct section *strtab, const char *str)
 {
-	Elf_Data *data;
-	Elf_Scn *s;
-	int len;
+	unsigned long offset;
 
 	if (!strtab) {
 		strtab = find_section_by_name(elf, ".strtab");
@@ -938,56 +950,77 @@ static int elf_add_string(struct elf *elf, struct section *strtab, const char *s
 			ERROR("can't find .strtab section");
 	}
 
-	s = elf_getscn(elf->elf, strtab->idx);
-	if (!s)
-		ERROR_ELF("elf_getscn");
+	offset = ALIGN_UP(strtab->sh.sh_size, strtab->sh.sh_addralign);
 
-	data = elf_newdata(s);
-	if (!data)
-		ERROR_ELF("elf_newdata");
+	elf_add_data(elf, strtab, str, strlen(str) + 1);
 
-	data->d_buf = strdup(str);
-	data->d_size = strlen(str) + 1;
-	data->d_align = 1;
-
-	len = strtab->sh.sh_size;
-	strtab->sh.sh_size += data->d_size;
-
-	mark_sec_changed(elf, strtab, true);
-
-	return len;
+	return offset;
 }
 
-struct section *elf_create_section(struct elf *elf, const char *name,
-				   size_t entsize, unsigned int nr)
+void *elf_add_data(struct elf *elf, struct section *sec, const void *data, size_t size)
 {
-	struct section *sec, *shstrtab;
-	size_t size = entsize * nr;
+	unsigned long offset;
 	Elf_Scn *s;
 
-	sec = malloc(sizeof(*sec));
-	ERROR_ON(!sec, "malloc");
-	memset(sec, 0, sizeof(*sec));
-
-	INIT_LIST_HEAD(&sec->symbol_list);
-
-	s = elf_newscn(elf->elf);
+	s = elf_getscn(elf->elf, sec->idx);
 	if (!s)
-		ERROR_ELF("elf_newscn");
-
-	sec->name = strdup(name);
-	ERROR_ON(!sec->name, "strdup");
-
-	sec->idx = elf_ndxscn(s);
+		ERROR_ELF("elf_getscn");
 
 	sec->data = elf_newdata(s);
 	if (!sec->data)
 		ERROR_ELF("elf_newdata");
 
+	sec->data->d_buf = calloc(1, size);
+	ERROR_ON(!sec->data->d_buf, "calloc");
+
+	if (data)
+		memcpy(sec->data->d_buf, data, size);
+
 	sec->data->d_size = size;
-	sec->data->d_align = 1;
+	sec->data->d_align = sec->sh.sh_addralign;
+
+	offset = ALIGN_UP(sec->sh.sh_size, sec->sh.sh_addralign);
+	sec->sh.sh_size = offset + size;
+
+	mark_sec_changed(elf, sec, true);
+
+	return sec->data->d_buf;
+}
+
+struct section *elf_create_section(struct elf *elf, const char *name,
+				   size_t size, size_t entsize,
+				   unsigned int type, unsigned int align,
+				   unsigned int flags)
+{
+	struct section *sec, *shstrtab;
+	Elf_Scn *s;
+
+	if (name && find_section_by_name(elf, name))
+		ERROR("section '%s' already exists", name);
+
+	sec = calloc(1, sizeof(*sec));
+	ERROR_ON(!sec, "calloc");
+
+	INIT_LIST_HEAD(&sec->symbol_list);
+
+	/* don't actually create the section, just the data structures */
+	if (type == SHT_NULL)
+		goto add;
+
+	s = elf_newscn(elf->elf);
+	if (!s)
+		ERROR_ELF("elf_newscn");
+
+	sec->idx = elf_ndxscn(s);
 
 	if (size) {
+		sec->data = elf_newdata(s);
+		if (!sec->data)
+			ERROR_ELF("elf_newdata");
+
+		sec->data->d_size = size;
+		sec->data->d_align = 1;
+
 		sec->data->d_buf = calloc(1, size);
 		ERROR_ON(!sec->data->d_buf, "calloc");
 	}
@@ -997,31 +1030,37 @@ struct section *elf_create_section(struct elf *elf, const char *name,
 
 	sec->sh.sh_size = size;
 	sec->sh.sh_entsize = entsize;
-	sec->sh.sh_type = SHT_PROGBITS;
-	sec->sh.sh_addralign = 1;
-	sec->sh.sh_flags = SHF_ALLOC;
+	sec->sh.sh_type = type;
+	sec->sh.sh_addralign = align;
+	sec->sh.sh_flags = flags;
 
-	/* Add section name to .shstrtab (or .strtab for Clang) */
-	shstrtab = find_section_by_name(elf, ".shstrtab");
-	if (!shstrtab) {
-		shstrtab = find_section_by_name(elf, ".strtab");
-		if (!shstrtab)
-			ERROR("can't find .shstrtab or .strtab section");
+	if (name) {
+		sec->name = strdup(name);
+		ERROR_ON(!sec->name, "strdup");
+
+		/* Add section name to .shstrtab (or .strtab for Clang) */
+		shstrtab = find_section_by_name(elf, ".shstrtab");
+		if (!shstrtab) {
+			shstrtab = find_section_by_name(elf, ".strtab");
+			if (!shstrtab)
+				ERROR("can't find .shstrtab or .strtab section");
+		}
+		sec->sh.sh_name = elf_add_string(elf, shstrtab, sec->name);
+
+		elf_hash_add(section_name, &sec->name_hash, str_hash(sec->name));
 	}
-	sec->sh.sh_name = elf_add_string(elf, shstrtab, sec->name);
 
+add:
 	list_add_tail(&sec->list, &elf->sections);
 	elf_hash_add(section, &sec->hash, sec->idx);
-	elf_hash_add(section_name, &sec->name_hash, str_hash(sec->name));
 
 	mark_sec_changed(elf, sec, true);
 
 	return sec;
 }
 
-static struct section *elf_create_rela_section(struct elf *elf,
-					       struct section *sec,
-					       unsigned int reloc_nr)
+struct section *elf_create_rela_section(struct elf *elf, struct section *sec,
+					unsigned int reloc_nr)
 {
 	struct section *rsec;
 	char *rsec_name;
@@ -1032,33 +1071,110 @@ static struct section *elf_create_rela_section(struct elf *elf,
 	strcpy(rsec_name, ".rela");
 	strcat(rsec_name, sec->name);
 
-	rsec = elf_create_section(elf, rsec_name, elf_rela_size(elf), reloc_nr);
-	free(rsec_name);
+	rsec = elf_create_section(elf, rsec_name, reloc_nr * elf_rela_size(elf),
+				  elf_rela_size(elf), SHT_RELA, elf_addr_size(elf),
+				  SHF_INFO_LINK);
 
-	rsec->data->d_type = ELF_T_RELA;
-	rsec->sh.sh_type = SHT_RELA;
-	rsec->sh.sh_addralign = elf_addr_size(elf);
 	rsec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx;
 	rsec->sh.sh_info = sec->idx;
-	rsec->sh.sh_flags = SHF_INFO_LINK;
 
-	rsec->relocs = calloc(sec_num_entries(rsec), sizeof(struct reloc));
-	ERROR_ON(!rsec->relocs, "calloc");
+	if (reloc_nr) {
+		rsec->data->d_type = ELF_T_RELA;
+		rsec->relocs = calloc(sec_num_entries(rsec), sizeof(struct reloc));
+		ERROR_ON(!rsec->relocs, "calloc");
+	}
 
 	sec->rsec = rsec;
+	free(rsec_name);
+
 	rsec->base = sec;
 
 	return rsec;
 }
 
+// TODO: preallocate sec->relocs so this doesn't happen often
+// TODO: can avoid for bundled sections
+static void elf_alloc_reloc(struct elf *elf, struct section *rsec)
+{
+	unsigned int nr_relocs = sec_num_entries(rsec);
+	struct reloc *old_relocs, *new_relocs;
+	struct symbol *sym;
+
+	old_relocs = rsec->relocs;
+	new_relocs = calloc(1, (nr_relocs + 1) * sizeof(struct reloc));
+	ERROR_ON(!new_relocs, "calloc");
+
+	if (!old_relocs)
+		goto done;
+
+	// update syms and relocs which reference the reloc
+	for_each_sym(elf, sym) {
+		struct reloc **reloc;
+
+		for (reloc = &sym->relocs; *reloc; ) {
+			struct reloc **next = &((*reloc)->sym_next_reloc);
+			if (*reloc >= old_relocs && *reloc < &old_relocs[nr_relocs]) {
+				*reloc = &new_relocs[*reloc - old_relocs];
+			}
+			reloc = next;
+		}
+	}
+
+	memcpy(new_relocs, old_relocs, (nr_relocs * sizeof(struct reloc)));
+
+	for (int i = 0; i < nr_relocs; i++) {
+		struct reloc *old = &old_relocs[i];
+		struct reloc *new = &new_relocs[i];
+		u32 key = reloc_hash(old);
+
+		elf_hash_del(reloc, &old->hash, key);
+		elf_hash_add(reloc, &new->hash, key);
+	}
+
+	free(old_relocs);
+done:
+	rsec->relocs = new_relocs;
+}
+
+struct reloc *elf_create_reloc(struct elf *elf, struct section *sec,
+			       unsigned long offset,
+			       struct symbol *sym, s64 addend,
+			       unsigned int type)
+{
+	struct section *rsec = sec->rsec;
+
+	if (!rsec)
+		rsec = elf_create_rela_section(elf, sec, 0);
+
+	if (find_reloc_by_dest(elf, sec, offset))
+		ERROR_FUNC(sec, offset, "duplicate reloc");
+
+	if (!rsec->data) {
+		rsec->data = elf_newdata(elf_getscn(elf->elf, rsec->idx));
+		rsec->data->d_align = 1;
+		rsec->data->d_type = ELF_T_RELA;
+	}
+
+	elf_alloc_reloc(elf, rsec);
+
+	rsec->sh.sh_size += elf_rela_size(elf);
+	rsec->data->d_size = rsec->sh.sh_size;
+	rsec->data->d_buf = realloc(rsec->data->d_buf, rsec->sh.sh_size);
+	return elf_init_reloc(elf, rsec, sec_num_entries(rsec) - 1, offset, sym,
+			      addend, type);
+}
+
 struct section *elf_create_section_pair(struct elf *elf, const char *name,
 					size_t entsize, unsigned int nr,
 					unsigned int reloc_nr)
 {
 	struct section *sec;
 
-	sec = elf_create_section(elf, name, entsize, nr);
+	sec = elf_create_section(elf, name, nr * entsize, entsize,
+				 SHT_PROGBITS, 1, SHF_ALLOC);
+
 	elf_create_rela_section(elf, sec, reloc_nr);
+
 	return sec;
 }
 
diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/objtool/elf.h
index 8585b9802e1b..e91bbe7f07bf 100644
--- a/tools/objtool/include/objtool/elf.h
+++ b/tools/objtool/include/objtool/elf.h
@@ -15,6 +15,8 @@
 #include <linux/jhash.h>
 #include <arch/elf.h>
 
+#define SYM_NAME_LEN		512
+
 #ifdef LIBELF_USE_DEPRECATED
 # define elf_getshdrnum    elf_getshnum
 # define elf_getshdrstrndx elf_getshstrndx
@@ -109,12 +111,33 @@ struct elf {
 struct elf *elf_open_read(const char *name, int flags);
 
 struct section *elf_create_section(struct elf *elf, const char *name,
-				   size_t entsize, unsigned int nr);
+				   size_t size, size_t entsize,
+				   unsigned int type, unsigned int align,
+				   unsigned int flags);
 struct section *elf_create_section_pair(struct elf *elf, const char *name,
 					size_t entsize, unsigned int nr,
 					unsigned int reloc_nr);
 
-struct symbol *elf_create_prefix_symbol(struct elf *elf, struct symbol *orig, long size);
+struct section *elf_create_rela_section(struct elf *elf, struct section *sec,
+					unsigned int reloc_nr);
+
+struct symbol *elf_create_symbol(struct elf *elf, const char *name,
+				 struct section *sec, unsigned int bind,
+				 unsigned int type, unsigned long offset,
+				 size_t size);
+struct symbol *elf_create_section_symbol(struct elf *elf, struct section *sec);
+struct symbol *elf_create_prefix_symbol(struct elf *elf, struct symbol *orig,
+					size_t size);
+
+struct reloc *elf_create_reloc(struct elf *elf, struct section *sec,
+			       unsigned long offset, struct symbol *sym,
+			       s64 addend, unsigned int type);
+void *elf_add_data(struct elf *elf, struct section *sec, const void *data,
+		   size_t size);
+
+struct reloc *elf_init_reloc(struct elf *elf, struct section *rsec,
+			     unsigned int reloc_idx, unsigned long offset,
+			     struct symbol *sym, s64 addend, unsigned int type);
 
 struct reloc *elf_init_reloc_text_sym(struct elf *elf, struct section *sec,
 				      unsigned long offset,
@@ -128,6 +151,8 @@ struct reloc *elf_init_reloc_data_sym(struct elf *elf, struct section *sec,
 				      struct symbol *sym,
 				      s64 addend);
 
+unsigned long elf_add_string(struct elf *elf, struct section *strtab, const char *str);
+
 void elf_write_insn(struct elf *elf, struct section *sec,
 		    unsigned long offset, unsigned int len,
 		    const char *insn);
@@ -138,6 +163,7 @@ struct section *find_section_by_name(const struct elf *elf, const char *name);
 struct symbol *find_func_by_offset(struct section *sec, unsigned long offset);
 struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset);
 struct symbol *find_symbol_by_name(const struct elf *elf, const char *name);
+struct symbol *find_global_symbol_by_name(const struct elf *elf, const char *name);
 struct symbol *find_symbol_containing(const struct section *sec, unsigned long offset);
 int find_symbol_hole_containing(const struct section *sec, unsigned long offset);
 struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, unsigned long offset);
diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c
index 56aca3845e20..3301128b5188 100644
--- a/tools/objtool/orc_gen.c
+++ b/tools/objtool/orc_gen.c
@@ -121,7 +121,11 @@ int orc_create(struct objtool_file *file)
 		return 0;
 	}
 	orc_sec = elf_create_section(file->elf, ".orc_unwind",
-				     sizeof(struct orc_entry), nr);
+				     nr * sizeof(struct orc_entry),
+				     sizeof(struct orc_entry),
+				     SHT_PROGBITS,
+				     1,
+				     SHF_ALLOC);
 
 	sec = elf_create_section_pair(file->elf, ".orc_unwind_ip", sizeof(int), nr, nr);
 
-- 
2.45.2


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ