Skip to content

Commit

Permalink
Support relocation kind 0003 and extend IMAGE_REL_ types.
Browse files Browse the repository at this point in the history
Specifically adds support for:

- IMAGE_REL_AMD64_ADDR32NB. (This is the "relocation kind 0003").

- IMAGE_REL_I386_DIR32NB. (This is the x86 version of the above).

- IMAGE_REL_AMD64_REL32_5. (This is documented but weirdly not implemented).
  • Loading branch information
Jonah Beckford committed Jul 29, 2024
1 parent 80496b5 commit 19aadf0
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 1 deletion.
3 changes: 2 additions & 1 deletion CHANGES
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
Next version
- GPR#127: Recognise hyphens in option names in the COFF .drectve section. Fixes #126 (Reza Barazesh)
- GPR#136: Fix parallel access crashes and misbehavior (David Allsopp, Jan Midtgaard, Antonin Décimo)

- GPR#140: Fixes #29. Support relocation kind 0003 (IMAGE_REL_AMD64_ADDR32NB) and
IMAGE_REL_I386_DIR32NB. Extend relative types to IMAGE_REL_AMD64_REL32_5. (Jonah Beckford)

Version 0.43
- GPR#108: Add -lgcc_s to Cygwin's link libraries, upstreaming a patch from the
Expand Down
21 changes: 21 additions & 0 deletions flexdll.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ typedef unsigned long uintnat;
#define RELOC_REL32_4 0x0003
#define RELOC_REL32_1 0x0004
#define RELOC_REL32_2 0x0005
#define RELOC_REL32_5 0x0006
#define RELOC_32NB 0x0007
#define RELOC_DONE 0x0100

typedef struct { UINT_PTR kind; char *name; UINT_PTR *addr; } reloc_entry;
Expand Down Expand Up @@ -356,6 +358,25 @@ static void relocate(resolver f, void *data, reloctbl *tbl, err_t *err) {
}
*((UINT32*) ptr->addr) = (INT32) s;
break;
case RELOC_REL32_5:
s -= (INT_PTR)(ptr -> addr) + 9;
s += *((INT32*) ptr -> addr);
if (s != (INT32) s) {
sprintf(err->message, "flexdll error: cannot relocate RELOC_REL32_5, target is too far: %p %p",(void *)((UINT_PTR) s), (void *) ((UINT_PTR)(INT32) s));
err->code = 3;
goto restore;
}
*((UINT32*) ptr->addr) = s;
break;
case RELOC_32NB:
s += *((INT32*) ptr -> addr);
if (s != (INT32) s) {
sprintf(err->message, "flexdll error: cannot relocate %s RELOC_32NB, target is too far: %p %p", ptr->name, (void *)((UINT_PTR) s), (void *) ((UINT_PTR)(INT32) s));
err->code = 3;
goto restore;
}
*((UINT32*) ptr->addr) = s;
break;
default:
fprintf(stderr, "flexdll: unknown relocation kind");
exit(2);
Expand Down
5 changes: 5 additions & 0 deletions reloc.ml
Original file line number Diff line number Diff line change
Expand Up @@ -433,13 +433,18 @@ let add_reloc_table obj obj_name p =
| `x64, 0x01 (* IMAGE_REL_AMD64_ADDR64 *) ->
0x0002 (* absolute, native size (32/64) *)

| `x86, 0x07 (* IMAGE_REL_I386_DIR32NB *)
| `x64, 0x03 (* IMAGE_REL_AMD64_ADDR32NB *) ->
0x0007 (* 32nb *)

| `x64, 0x04 (* IMAGE_REL_AMD64_REL32 *)
| `x86, 0x14 (* IMAGE_REL_I386_REL32 *) when not !no_rel_relocs ->
0x0001 (* rel32 *)

| `x64, 0x05 when not !no_rel_relocs -> 0x0004 (* rel32_1 *)
| `x64, 0x08 when not !no_rel_relocs-> 0x0003 (* rel32_4 *)
| `x64, 0x06 when not !no_rel_relocs-> 0x0005 (* rel32_2 *)
| `x64, 0x09 when not !no_rel_relocs-> 0x0006 (* rel32_5 *)

| (`x86 | `x64), (0x0a (* IMAGE_REL_{I386|AMD64}_SECTION *) |
0x0b (* IMAGE_REL_{I386|AMD64}_SECREL*) ) ->
Expand Down

0 comments on commit 19aadf0

Please sign in to comment.