mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-30 13:58:34 +00:00
pie: piegen -- Handle SHN_ABS symbols
For example some linkers generate @__export_parasite_args as symbol which won't relocate. Handle such case properly. Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
committed by
Pavel Emelyanov
parent
e6a1097265
commit
a65bffe323
@@ -185,16 +185,16 @@ int handle_elf(void *mem, size_t size)
|
|||||||
#endif
|
#endif
|
||||||
if (strncmp(name, "__export", 8))
|
if (strncmp(name, "__export", 8))
|
||||||
continue;
|
continue;
|
||||||
if (sym->st_shndx && sym->st_shndx < hdr->e_shnum) {
|
if ((sym->st_shndx && sym->st_shndx < hdr->e_shnum) || sym->st_shndx == SHN_ABS) {
|
||||||
sh_src = sec_hdrs[sym->st_shndx];
|
if (sym->st_shndx == SHN_ABS) {
|
||||||
ptr_func_exit(sh_src);
|
sh_src = NULL;
|
||||||
#if 0
|
} else {
|
||||||
if (ELF_ST_TYPE(sym->st_info) == STT_FUNC ||
|
sh_src = sec_hdrs[sym->st_shndx];
|
||||||
ELF_ST_TYPE(sym->st_info) == STT_OBJECT)
|
ptr_func_exit(sh_src);
|
||||||
#endif
|
}
|
||||||
pr_out("#define %s%s 0x%lx\n",
|
pr_out("#define %s%s 0x%lx\n",
|
||||||
opts.prefix_name, name,
|
opts.prefix_name, name,
|
||||||
(unsigned long)(sym->st_value + sh_src->sh_addr));
|
(unsigned long)(sym->st_value + (sh_src ? sh_src->sh_addr : 0)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -222,7 +222,6 @@ int handle_elf(void *mem, size_t size)
|
|||||||
s32 addend32, value32;
|
s32 addend32, value32;
|
||||||
unsigned long place;
|
unsigned long place;
|
||||||
const char *name;
|
const char *name;
|
||||||
Shdr_t *sh_src;
|
|
||||||
void *where;
|
void *where;
|
||||||
Sym_t *sym;
|
Sym_t *sym;
|
||||||
|
|
||||||
@@ -241,9 +240,6 @@ int handle_elf(void *mem, size_t size)
|
|||||||
where = mem + sh_rel->sh_offset + r->rel.r_offset;
|
where = mem + sh_rel->sh_offset + r->rel.r_offset;
|
||||||
ptr_func_exit(where);
|
ptr_func_exit(where);
|
||||||
|
|
||||||
sh_src = sec_hdrs[sym->st_shndx];
|
|
||||||
ptr_func_exit(sh_src);
|
|
||||||
|
|
||||||
pr_debug("\t\tr_offset 0x%-4lx r_info 0x%-4lx / sym 0x%-2lx type 0x%-2lx symsecoff 0x%-4lx\n",
|
pr_debug("\t\tr_offset 0x%-4lx r_info 0x%-4lx / sym 0x%-2lx type 0x%-2lx symsecoff 0x%-4lx\n",
|
||||||
(unsigned long)r->rel.r_offset, (unsigned long)r->rel.r_info,
|
(unsigned long)r->rel.r_offset, (unsigned long)r->rel.r_info,
|
||||||
(unsigned long)ELF_R_SYM(r->rel.r_info),
|
(unsigned long)ELF_R_SYM(r->rel.r_info),
|
||||||
@@ -277,11 +273,26 @@ int handle_elf(void *mem, size_t size)
|
|||||||
|
|
||||||
place = sh_rel->sh_addr + r->rel.r_offset;
|
place = sh_rel->sh_addr + r->rel.r_offset;
|
||||||
|
|
||||||
pr_debug("\t\t\tvalue 0x%-8lx addend32 %-4d addend64 %-8ld symname %s\n",
|
pr_debug("\t\t\tvalue 0x%-8lx addend32 %-4d addend64 %-8ld place %-8lx symname %s\n",
|
||||||
(unsigned long)sym->st_value, addend32, (long)addend64, name);
|
(unsigned long)sym->st_value, addend32, (long)addend64, (long)place, name);
|
||||||
|
|
||||||
value32 = (s32)sh_src->sh_addr + (s32)sym->st_value;
|
if (sym->st_shndx == SHN_ABS) {
|
||||||
value64 = (s64)sh_src->sh_addr + (s64)sym->st_value;
|
value32 = (s32)sym->st_value;
|
||||||
|
value64 = (s64)sym->st_value;
|
||||||
|
} else {
|
||||||
|
Shdr_t *sh_src;
|
||||||
|
|
||||||
|
if ((unsigned)sym->st_shndx > (unsigned)hdr->e_shnum) {
|
||||||
|
pr_err("Unexpected symbol section index %u/%u\n",
|
||||||
|
(unsigned)sym->st_shndx, hdr->e_shnum);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
sh_src = sec_hdrs[sym->st_shndx];
|
||||||
|
ptr_func_exit(sh_src);
|
||||||
|
|
||||||
|
value32 = (s32)sh_src->sh_addr + (s32)sym->st_value;
|
||||||
|
value64 = (s64)sh_src->sh_addr + (s64)sym->st_value;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef ELF_PPC64
|
#ifdef ELF_PPC64
|
||||||
/* Snippet from the OpenPOWER ABI for Linux Supplement:
|
/* Snippet from the OpenPOWER ABI for Linux Supplement:
|
||||||
@@ -410,7 +421,7 @@ int handle_elf(void *mem, size_t size)
|
|||||||
(unsigned int)place, addend32, value32);
|
(unsigned int)place, addend32, value32);
|
||||||
break;
|
break;
|
||||||
case R_X86_64_64: /* Symbol + Addend (8 bytes) */
|
case R_X86_64_64: /* Symbol + Addend (8 bytes) */
|
||||||
pr_debug("\t\t\t\tR_X86_64_64 at 0x%-4lx val 0x%lx\n", place, value64);
|
pr_debug("\t\t\t\tR_X86_64_64 at 0x%-4lx val 0x%lx\n", place, (long)value64);
|
||||||
pr_out(" { .offset = 0x%-8x, .type = PIEGEN_TYPE_LONG, "
|
pr_out(" { .offset = 0x%-8x, .type = PIEGEN_TYPE_LONG, "
|
||||||
".addend = %-8ld, .value = 0x%-16lx, }, /* R_X86_64_64 */\n",
|
".addend = %-8ld, .value = 0x%-16lx, }, /* R_X86_64_64 */\n",
|
||||||
(unsigned int)place, (long)addend64, (long)value64);
|
(unsigned int)place, (long)addend64, (long)value64);
|
||||||
|
Reference in New Issue
Block a user