R_PPC64_REL24 is reallly "PC-rel. 26 bit, word aligned:
Just like R_PPC_REL24 modified: linker.cpp
This commit is contained in:
parent
fdcdaf596a
commit
fabda4df3a
@ -835,18 +835,27 @@ void ElfLinkerPpc64le::relocate1(const Relocation *rel, byte *location, upx_uint
|
||||
/* value will hold relative displacement */
|
||||
value -= rel->section->offset + rel->offset;
|
||||
|
||||
if (strcmp(type, "8") == 0) {
|
||||
if (strncmp(type, "14", 2) == 0) { // for "14" and "14S"
|
||||
if (3 & value)
|
||||
internal_error("unaligned word displacement");
|
||||
// FIXME: displacement overflow?
|
||||
set_le32(location, (0xffff0003 & get_le32(location)) + (0x0000fffc & value));
|
||||
}
|
||||
else if (strncmp(type, "24", 2) == 0) { // for "24" and "24S"
|
||||
if (3 & value)
|
||||
internal_error("unaligned word displacement");
|
||||
// FIXME: displacement overflow?
|
||||
set_le32(location, (0xfc000003 & get_le32(location)) + (0x03fffffc & value));
|
||||
}
|
||||
else if (strcmp(type, "8") == 0) {
|
||||
int displ = (signed char) *location + (int) value;
|
||||
if (range_check && (displ < -128 || displ > 127))
|
||||
internal_error("target out of range (%d) in reloc %s:%x\n", displ, rel->section->name,
|
||||
rel->offset);
|
||||
*location += value;
|
||||
} else if (strncmp(type, "14", 2) == 0) // for "14" and "14S"
|
||||
set_le16(location, get_le16(location) + value);
|
||||
}
|
||||
else if (strcmp(type, "16") == 0)
|
||||
set_le16(location, get_le16(location) + value);
|
||||
else if (strncmp(type, "24", 2) == 0) // for "24" and "24S"
|
||||
set_le24(location, get_le24(location) + value);
|
||||
else if (strncmp(type, "32", 2) == 0) // for "32" and "32S"
|
||||
set_le32(location, get_le32(location) + value);
|
||||
else if (strcmp(type, "64") == 0)
|
||||
@ -869,18 +878,41 @@ void ElfLinkerPpc64::relocate1(const Relocation *rel, byte *location, upx_uint64
|
||||
return super::relocate1(rel, location, value, type);
|
||||
type += 11;
|
||||
|
||||
bool range_check = false;
|
||||
if (strncmp(type, "PC", 2) == 0) {
|
||||
type += 2;
|
||||
range_check = true;
|
||||
}
|
||||
|
||||
// We have "R_PPC64_REL" or "R_PPC64_RELPC" as a prefix.
|
||||
/* value will hold relative displacement */
|
||||
value -= rel->section->offset + rel->offset;
|
||||
|
||||
if (strncmp(type, "14", 2) == 0) // for "14" and "14S"
|
||||
set_be16(2 + location, get_be16(2 + location) + value);
|
||||
else if (strncmp(type, "24", 2) == 0) // for "24" and "24S"
|
||||
set_be24(1 + location, get_be24(1 + location) + value);
|
||||
if (strncmp(type, "14", 2) == 0) { // for "14" and "14S"
|
||||
if (3 & value)
|
||||
internal_error("unaligned word displacement");
|
||||
// FIXME: displacement overflow?
|
||||
set_be32(location, (0xffff0003 & get_be32(location)) + (0x0000fffc & value));
|
||||
}
|
||||
else if (strncmp(type, "24", 2) == 0) { // for "24" and "24S"
|
||||
if (3 & value)
|
||||
internal_error("unaligned word displacement");
|
||||
// FIXME: displacement overflow?
|
||||
set_be32(location, (0xfc000003 & get_be32(location)) + (0x03fffffc & value));
|
||||
}
|
||||
else if (strcmp(type, "8") == 0) {
|
||||
int displ = (signed char) *location + (int) value;
|
||||
if (range_check && (displ < -128 || displ > 127))
|
||||
internal_error("target out of range (%d) in reloc %s:%x\n", displ, rel->section->name,
|
||||
rel->offset);
|
||||
*location += value;
|
||||
}
|
||||
else if (strcmp(type, "16") == 0)
|
||||
set_be16(location, get_be16(location) + value);
|
||||
else if (strncmp(type, "32", 2) == 0) // for "32" and "32S"
|
||||
set_be32(location, get_be32(location) + value);
|
||||
else if (strcmp(type, "64") == 0)
|
||||
set_be64(location, get_be64(location) + value);
|
||||
else
|
||||
super::relocate1(rel, location, value, type);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user