diff options
Diffstat (limited to 'tools/relocate-rela.c')
-rw-r--r-- | tools/relocate-rela.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/tools/relocate-rela.c b/tools/relocate-rela.c index 6a52401..f0bc548 100644 --- a/tools/relocate-rela.c +++ b/tools/relocate-rela.c @@ -63,7 +63,7 @@ int main(int argc, char **argv) { FILE *f; int i, num; - uint64_t rela_start, rela_end, text_base; + uint64_t rela_start, rela_end, text_base, file_size; if (argc != 5) { fprintf(stderr, "Statically apply ELF rela relocations\n"); @@ -87,8 +87,7 @@ int main(int argc, char **argv) return 3; } - if (rela_start > rela_end || rela_start < text_base || - (rela_end - rela_start) % sizeof(Elf64_Rela)) { + if (rela_start > rela_end || rela_start < text_base) { fprintf(stderr, "%s: bad rela bounds\n", argv[0]); return 3; } @@ -96,6 +95,21 @@ int main(int argc, char **argv) rela_start -= text_base; rela_end -= text_base; + fseek(f, 0, SEEK_END); + file_size = ftell(f); + rewind(f); + + if (rela_end > file_size) { + // Most likely compiler inserted some section that didn't get + // objcopy-ed into the final binary + rela_end = file_size; + } + + if ((rela_end - rela_start) % sizeof(Elf64_Rela)) { + fprintf(stderr, "%s: rela size isn't a multiple of Elf64_Rela\n", argv[0]); + return 3; + } + num = (rela_end - rela_start) / sizeof(Elf64_Rela); for (i = 0; i < num; i++) { |