<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://vegard.wiki/mediawiki/index.php?action=history&amp;feed=atom&amp;title=Thunk</id>
	<title>Thunk - Revision history</title>
	<link rel="self" type="application/atom+xml" href="http://vegard.wiki/mediawiki/index.php?action=history&amp;feed=atom&amp;title=Thunk"/>
	<link rel="alternate" type="text/html" href="http://vegard.wiki/mediawiki/index.php?title=Thunk&amp;action=history"/>
	<updated>2026-07-04T18:20:06Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.41.1</generator>
	<entry>
		<id>http://vegard.wiki/mediawiki/index.php?title=Thunk&amp;diff=151&amp;oldid=prev</id>
		<title>Vegard: /* Definition */ fix ridiculous typo</title>
		<link rel="alternate" type="text/html" href="http://vegard.wiki/mediawiki/index.php?title=Thunk&amp;diff=151&amp;oldid=prev"/>
		<updated>2020-02-14T18:32:24Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Definition: &lt;/span&gt; fix ridiculous typo&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 18:32, 14 February 2020&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 10:&lt;/td&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 10:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;#ifndef PAGE_SIZE&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;#ifndef PAGE_SIZE&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;#define PAGE_SIZE &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;4095&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;#define PAGE_SIZE &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;4096&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;#endif&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;#endif&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;!-- diff cache key mediawiki:diff:1.41:old-135:rev-151:wikidiff2=table:1.13.0:bc2a06be --&gt;
&lt;/table&gt;</summary>
		<author><name>Vegard</name></author>
	</entry>
	<entry>
		<id>http://vegard.wiki/mediawiki/index.php?title=Thunk&amp;diff=135&amp;oldid=prev</id>
		<title>Vegard: /* Definition */</title>
		<link rel="alternate" type="text/html" href="http://vegard.wiki/mediawiki/index.php?title=Thunk&amp;diff=135&amp;oldid=prev"/>
		<updated>2020-01-31T08:47:48Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Definition&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 08:47, 31 January 2020&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 53:&lt;/td&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 53:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;}&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;}&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;void free_thunk(&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;thinked_fn&lt;/del&gt; fn)&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;void free_thunk(&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;thunked_fn&lt;/ins&gt; fn)&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;{&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;{&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;        munmap((void *) fn, PAGE_SIZE);&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;        munmap((void *) fn, PAGE_SIZE);&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;!-- diff cache key mediawiki:diff:1.41:old-134:rev-135:wikidiff2=table:1.13.0:bc2a06be --&gt;
&lt;/table&gt;</summary>
		<author><name>Vegard</name></author>
	</entry>
	<entry>
		<id>http://vegard.wiki/mediawiki/index.php?title=Thunk&amp;diff=134&amp;oldid=prev</id>
		<title>Vegard: new page</title>
		<link rel="alternate" type="text/html" href="http://vegard.wiki/mediawiki/index.php?title=Thunk&amp;diff=134&amp;oldid=prev"/>
		<updated>2020-01-31T07:45:26Z</updated>

		<summary type="html">&lt;p&gt;new page&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;It is possible in C to &amp;quot;bake&amp;quot; one or more arguments into a function pointer that takes no arguments, thus solving the problem of libraries that take a callback function without a data pointer.&lt;br /&gt;
&lt;br /&gt;
Below is one possible implementation for x86-64 that bakes a single argument into a thunk. Error handling may need to be adjusted for specific use cases.&lt;br /&gt;
&lt;br /&gt;
=== Definition ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/mman.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifndef PAGE_SIZE&lt;br /&gt;
#define PAGE_SIZE 4095&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
typedef void (*unthunked_fn)(void *);&lt;br /&gt;
typedef void (*thunked_fn)(void);&lt;br /&gt;
&lt;br /&gt;
thunked_fn make_thunk(unthunked_fn fn, void *data)&lt;br /&gt;
{&lt;br /&gt;
        void *ptr = mmap(NULL, PAGE_SIZE,&lt;br /&gt;
                PROT_READ | PROT_WRITE | PROT_EXEC,&lt;br /&gt;
                MAP_PRIVATE | MAP_ANONYMOUS,&lt;br /&gt;
                -1, 0);&lt;br /&gt;
        if (ptr == MAP_FAILED)&lt;br /&gt;
                return NULL;&lt;br /&gt;
&lt;br /&gt;
        struct {&lt;br /&gt;
                unsigned char movabs_rdi[10];&lt;br /&gt;
                unsigned char movabs_rax[10];&lt;br /&gt;
                unsigned char jmpq[2];&lt;br /&gt;
        } *page = ptr;&lt;br /&gt;
&lt;br /&gt;
        /* movabs $..., %rdi */&lt;br /&gt;
        page-&amp;gt;movabs_rdi[0] = 0x48;&lt;br /&gt;
        page-&amp;gt;movabs_rdi[1] = 0xbf;&lt;br /&gt;
        for (unsigned int i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
                page-&amp;gt;movabs_rdi[2 + i] = (unsigned long) data &amp;gt;&amp;gt; (8 * i);&lt;br /&gt;
&lt;br /&gt;
        /* movabs $..., %rax */&lt;br /&gt;
        page-&amp;gt;movabs_rax[0] = 0x48;&lt;br /&gt;
        page-&amp;gt;movabs_rax[1] = 0xb8;&lt;br /&gt;
        for (unsigned int i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
                page-&amp;gt;movabs_rax[2 + i] = (unsigned long) fn &amp;gt;&amp;gt; (8 * i);&lt;br /&gt;
&lt;br /&gt;
        /* jmpq %rax */&lt;br /&gt;
        page-&amp;gt;jmpq[0] = 0xff;&lt;br /&gt;
        page-&amp;gt;jmpq[1] = 0xe0;&lt;br /&gt;
&lt;br /&gt;
        /* Optional; only needed for CPUs with W^X */&lt;br /&gt;
        mprotect(ptr, PAGE_SIZE, PROT_READ | PROT_EXEC);&lt;br /&gt;
&lt;br /&gt;
        return (thunked_fn) page;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void free_thunk(thinked_fn fn)&lt;br /&gt;
{&lt;br /&gt;
        munmap((void *) fn, PAGE_SIZE);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Usage ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
static void print_str(void *data)&lt;br /&gt;
{&lt;br /&gt;
        printf(&amp;quot;print_str: %s\n&amp;quot;, (const char *) data);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[])&lt;br /&gt;
{&lt;br /&gt;
        thunked_fn fn = make_thunk(print_str, &amp;quot;Hello world!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        /* Prints &amp;quot;Hello world!&amp;quot; */&lt;br /&gt;
        fn();&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;C Closures as a Library&amp;quot;: https://nullprogram.com/blog/2017/01/08/&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;br /&gt;
[[Category:C]]&lt;/div&gt;</summary>
		<author><name>Vegard</name></author>
	</entry>
</feed>