-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support relocation kind 0003 and extend IMAGE_REL_ types #141
base: master
Are you sure you want to change the base?
Conversation
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).
flexdll.c
Outdated
err->code = 3; | ||
goto restore; | ||
} | ||
*((UINT32*) ptr->addr) = s; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just for my own understanding:
- In LLVM, this relocation is implemented by
add32(off, s)
, so thatoff
in LLVM corresponds toptr->addr
in Flexlink ands
in LLVM corresponds tos
in Flexlink. - The relocation
IMAGE_REL_AMD64_ADDR64
in LLVM (RELOC_ABS
in Flexlink) is implemented byadd64(off, s + imageBase)
, so thats + imageBase
in LLVM corresponds tos
in Flexlink.
Do you understand why the s
arguments do not seem to match between the two cases?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Going one step further, those equations imply that imageBase = 0
.
I spent a lot of time looking and I couldn't find out why IMAGE_REL_AMD64_ADDR64 seems to work. The math for all the other relocation kinds make sense.
However, two things ...
- The
/base:
base addresslink.exe
option is fixed for OCaml executable to be0x10000
atLine 47 in 80496b5
let base_addr = ref "0x10000"
and also the same in
Line 77 in 80496b5
let image_base = 0x10000l in
for OCaml plugins / stubs. - All of the relative relocations from this section of code are translated by:
Lines 470 to 475 in 80496b5
Reloc.abs !machine sect (Int32.of_int (Buffer.length data)) strsym; int_to_buf data pos; Reloc.abs !machine sect (Int32.of_int (Buffer.length data)) (Lazy.force secsym); int_to_buf data (Int32.to_int rel.addr);
into absolute relocations byReloc.abs
:Lines 437 to 444 in 80496b5
module Reloc = struct let abs machine sec addr sym = let rtype = match machine with | `x86 -> 0x06 | `x64 -> 0x01 in sec.relocs <- { addr = addr; symbol = sym; rtype = rtype } :: sec.relocs
So my suspicion was that the Reloc.abs
absolute relocations were being translated at CreateProcess time by ntdll.LdrInitializeThunk
(or whatever is reading the PE .reloc
section) to complete the imageBase
adjustment.
@dra27, any chance you can explain why base_addr
(or image_base
for DLLs) is not used in the calculations?
(These calculations are undocumented in flexdll and fairly complicated)
I just noticed that I have not extended the DLL logic at Lines 235 to 253 in 80496b5
That DLL logic does use the I don't really have a way to test that. The stubs/plugins generated by OCaml do not have those relocations (which is also why I didn't notice them). |
387e4b8
to
19aadf0
Compare
Co-authored-by: Antonin Décimo <[email protected]>
Fixes #29 .
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).
Tested with my ucrt branch https://github.com/jonahbeckford/flexdll/tree/0.43%2Bucrt where relocation kind 0003 occurs often. It especially occurs in "normal" C libraries (ucvrt;
/MD
) that are linked into an OCaml executable. None of the tested code used/GS-
.References: