diff options
| author | Michael Forney <[email protected]> | 2021-10-19 23:55:40 -0700 |
|---|---|---|
| committer | Andrew Chambers <[email protected]> | 2021-10-20 20:04:52 +1300 |
| commit | 7a5f42708b3b30bdfbc263db010832172d99a02d (patch) | |
| tree | 170ce7607596bf671d0db1e0ff1fda198b94018e | |
| parent | d0bfca3339527c692831fc54c9b81bb24de59945 (diff) | |
Fix cut-off check for 1-byte jump offset
The size of a 1-byte jump is 2, so the offset to the end of a the
jump for a negative distance is `distance - 2`. Similarly, the size
of a 4-byte jump is 5 or 6, so the offset from the end of the 4-byte
jump is `distance - 5` or `distance - 6`.
Also, add an assert to make sure the offset really does fit in 1 byte.
| -rw-r--r-- | main.c | 6 |
1 files changed, 4 insertions, 2 deletions
@@ -1,3 +1,4 @@ +#include <assert.h> #include "minias.h" /* Parsed assembly */ @@ -504,7 +505,7 @@ assemblejmp(const Jmp *j) } else { distance = target->wco - cursection->hdr.sh_size; } - if ((distance - 1) >= -128 && (distance - 5) <= 127) { + if (distance - 2 >= INT8_MIN && distance - (j->cc ? 6 : 5) <= INT8_MAX) { jmpsize = 1; } else { jmpsize = 4; @@ -922,7 +923,8 @@ resolvereloc(Relocation *reloc) case R_X86_64_PC8: rdata = &reloc->section->data[reloc->offset]; value = sym->offset - reloc->offset + reloc->addend; - rdata[0] = ((uint8_t)value & 0xff); + assert(value >= INT8_MIN && value <= INT8_MAX); + rdata[0] = value; return 1; case R_X86_64_PC32: rdata = &reloc->section->data[reloc->offset]; |
