diff --git a/src/linker.cpp b/src/linker.cpp index 391e6dfc..e018b0ae 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -472,9 +472,9 @@ void ElfLinker::relocate() { value = rel->value->section->offset + rel->value->offset + rel->add; } upx_byte *location = rel->section->output + rel->offset; - // printf("%-28s %-28s %-10s 0x%16llx 0x%16llx\n", rel->section->name, rel->value->name, + // printf("%-28s %-28s %-10s %#16llx %#16llx\n", rel->section->name, rel->value->name, // rel->type, (long long) value, (long long) value - rel->section->offset - rel->offset); - // printf(" %llx %d %llx %d %llx : %d\n", (long long) value, rel->value->section->offset, + // printf(" %llx %d %llx %d %llx : %d\n", (long long) value, (int)rel->value->section->offset, // rel->value->offset, rel->offset, (long long) rel->add, *location); relocate1(rel, location, value, rel->type); } @@ -607,11 +607,17 @@ void ElfLinkerARM64::relocate1(const Relocation *rel, upx_byte *location, upx_ui set_le32(location, get_le32(location) + value); else if (!strcmp(type, "64")) set_le64(location, get_le64(location) + value); - } else if (!strcmp(type, "ABS32") == 0) { + } else if (!strcmp(type, "ABS32")) { set_le32(location, get_le32(location) + value); - } else if (!strcmp(type, "ABS64") == 0) { + } else if (!strcmp(type, "ABS64")) { set_le64(location, get_le64(location) + value); } + else if (!strcmp(type, "CONDBR19")) { + value -= rel->section->offset + rel->offset; + uint32_t const m19 = ~(~0u << 19); + uint32_t w = get_le32(location); + set_le32(location, (w &~(m19<<5)) | ((((w>>5) + (value>>2)) & m19) << 5) ); + } else super::relocate1(rel, location, value, type); }