GP-2664 Docs for unions, relative pointers

This commit is contained in:
caheckman 2022-10-05 19:11:10 -04:00
parent f7bb9e9e43
commit 79d95710e4
9 changed files with 537 additions and 70 deletions

View file

@ -26,8 +26,8 @@
vector<ArchitectureCapability *> ArchitectureCapability::thelist; vector<ArchitectureCapability *> ArchitectureCapability::thelist;
const uint4 ArchitectureCapability::majorversion = 4; const uint4 ArchitectureCapability::majorversion = 5;
const uint4 ArchitectureCapability::minorversion = 1; const uint4 ArchitectureCapability::minorversion = 0;
AttributeId ATTRIB_ADJUSTVMA = AttributeId("adjustvma",103); AttributeId ATTRIB_ADJUSTVMA = AttributeId("adjustvma",103);
AttributeId ATTRIB_ENABLE = AttributeId("enable",104); AttributeId ATTRIB_ENABLE = AttributeId("enable",104);

View file

@ -2071,6 +2071,134 @@
</informalexample> </informalexample>
</para> </para>
</sect4> </sect4>
<sect4 id="TypeUnion">
<title>Unions</title>
<para>
Unions data-types are fully supported. The Decompiler does not automatically infer unions
when analyzing a function; it propagates them into the function from explicitly
annotated sources, like input parameters or global variables.
</para>
<para>
A union data-type, similarly to a structure, is made up of component data-types
called <emphasis>fields</emphasis>. But unlike a structure, a union's fields all share the same underlying
storage. When the union is applied to a variable, each field potentially describes the whole variable.
At any given point where the variable is read or written, a different field may be in effect, even if the
underlying data hasn't changed. The decompiler attempts to infer the particular field by following data-flow
to or from the point of use to determine which field best aligns with the specific operations being applied to the
variable. The name of this recovered field is then printed in Decompiler output using syntax similar to that
used for structure fields.
</para>
<para>
Depending on the number and variety of fields within the union, it may not be possible
to fully distinguish which field is being used in a specific context. In this situation,
the Decompiler chooses the first field from the list of best matches. The user has the
option of changing this choice with the <xref linkend="ActionForceField"/> action.
</para>
</sect4>
<sect4 id="TypeTypedef">
<title>Typedefs</title>
<para>
Typedef data-types are fully supported. The Decompiler does not automatically infer typedefs
when analyzing a function; it propagates them into the function from explicitly annotated sources.
</para>
<para>
A <emphasis role="bold">typedef</emphasis> is copy of another data-type but with an alternate name.
In most cases it can be used interchangeably with the data-type it copies.
In general, the Decompiler treats a typedef as a distinct data-type, and it will maintain its identify
when it is assigned to variables and is propagated through data-flow.
</para>
<para>
Ghidra supports a specific set of attributes that can be placed directly on a typedef
that then distinguish it from the data-type it copies. This allows Ghidra to support some
non-standard data-types, although the typedef and its copy are no longer interchangeable.
The decompiler supports the following typedef properties:
<itemizedlist mark='none'>
<listitem>Component Offset - See <xref linkend="AttributeOffsetPointer"/></listitem>
<listitem>Address Space - See <xref linkend="AttributeAddressPointer"/></listitem>
</itemizedlist>
</para>
</sect4>
</sect3>
<sect3 id="AnnotePointerAttributes">
<title>Pointer Attributes</title>
<para>
The Decompiler supports some specialized attributes that can be applied to pointer data-types, like offsets
and address spaces (See below). Ghidra implements these attributes on top of <emphasis>typedef</emphasis> data-types only. In
order to add attributes to pointers, a typedef of the underlying pointer data-type must be created first.
Attributes can then be placed directly on the typedef from the Data Type Manager window
(See <link xlink:href="help/topics/DataTypeManagerPlugin/data_type_manager_description.htm#Pointer_Typedef_Settings">Pointer-Typedef Settings</link>).
</para>
<sect4 id="AttributeOffsetPointer">
<title>Offset Pointers</title>
<para>
An <emphasis role="bold">offset pointer</emphasis> points at a fixed offset relative to the start of its
underlying data-type. Typically the underlying data-type is a structure and the pointer points at a
specific field in the interior of the structure. But in general, the underlying data-type can be anything,
and the offset can point anywhere relative to that data-type, including either before or after.
</para>
<para>
An offset pointer is defined with all the same properties of a normal pointer. It has an underlying
data-type and a size. On top of this an <emphasis role="bold">offset</emphasis> is specified
as an integer attribute on the pointer (typedef). This is the number of bytes that need to be
added to the start of the underlying data-type to obtain the address actually being pointed at.
</para>
<para>
Because the <emphasis>underlying</emphasis> data-type does not start directly at the address
contained in the offset pointer, one can also refer to the offset pointer's
<emphasis role="bold">direct</emphasis> data-type, i.e. the data-type that <emphasis>is</emphasis>
directly at the address contained in the pointer. If the pointer's offset is positive (and small),
the direct data-type will generally be that of a field of the <emphasis>underlying</emphasis>
data-type. If the offset is bigger than the size of the underlying data-type or is negative,
the direct data-type will be <emphasis>undefined</emphasis>.
</para>
<para>
Offset pointers occur in code where the compiler has maintained knowledge of the position of
an underlying data-type relative to a pointer, even if the pointer no longer points directly at the data-type.
Because of this, the code may still access fields of the underlying data-type through the pointer.
Annotating a variable with an offset pointer allows the Decompiler to recover these accesses.
</para>
<para>
Within the Decompiler's output, the token <code>ADJ</code> is used to indicate that the code is
accessing the underlying data-type through the offset pointer. The token uses functional syntax
to indicate the particular offset pointer. Then, once the <code>ADJ</code> token is
applied, additional pointer syntax is used, i.e. <code>-&gt;</code>, to indicate what part
of the underlying data-type is being accessed.
<informalexample>
<programlisting>
ADJ(structoffptr)->field1 = 2; // Accessing the underlying structure's field
iVar1 = *ADJ(intoffptr); // Accessing the underlying integer data-type
ADJ(arrayoffptr)[4] = iVar2; // Accessing the underlying array
</programlisting>
</informalexample>
If the offset pointer appears in Decompiler output without the <code>ADJ</code> token being
applied, it is being treated as if it were a normal pointer to its direct
data-type. This generally indicates the pointer is being used to access data outside the
underlying data-type.
</para>
</sect4>
<sect4 id="AttributeAddressPointer">
<title>Address Space Pointers</title>
<para>
An <emphasis role="bold">address space pointer</emphasis> is a normal pointer data-type with a specific
address space associated to it (See <xref linkend="ConceptAddressSpace"/>). Its created by setting
the Address Space attribute on a typedef of a pointer. The attribute value is the name of the specific
address space.
</para>
<para>
Address space pointers are useful, when a program architecture supports more than one address space
containing addressable memory, such as separate <code>code</code> and <code>data</code> address spaces.
For a program and a specific section of its code that manipulates a pointer, it may not be easy to determine
which address space is being referred to. Address space pointers provide an additional annotation mechanism
to help the decompiler identify the correct address space for a pointer in context.
</para>
<para>
The Decompiler will automatically propagate an address space pointer data-type from parameters and
other annotated variables associated with a function. Any constant that the pointer reaches via propagation
is assumed to point into the address space associated with the pointer. The correct symbol can then
be looked up, further informing the Decompiler output.
</para>
</sect4>
</sect3> </sect3>
<sect3 id="AnnoteForcing"> <sect3 id="AnnoteForcing">
@ -2509,17 +2637,19 @@
<para> <para>
The <emphasis role="bold">volatile</emphasis> mutability setting indicates that values within The <emphasis role="bold">volatile</emphasis> mutability setting indicates that values within
the memory region may change unexpectedly, even if the code currently executing does not directly the memory region may change unexpectedly, even if the code currently executing does not directly
write to it. If a volatile variable is accessed in a function being analyzed by the Decompiler, write to it. Accessing a variable within a volatile region, either reading or writing, can have other
each specific access is replaced with a built-in function call, which prevents constant propagation side-effects on the machine state, and it cannot in general be treated as normal variable.
and other transforms across the access. The built-in functions are named based on If a volatile variable is accessed in a function being analyzed by the Decompiler,
whether the access is a <emphasis>read</emphasis> or <emphasis>write</emphasis> and on the <emphasis>size</emphasis> each access is expressed as a copy statement on its own line, separated from other expressions,
of the access. Within the Decompiler output, the first parameter to a built-in function is a symbol so that the its position within the code and any sequence of accesses is clearly indicated.
indicating the volatile variable. The function returns a value in the case of a volatile read or Any access, either read or write, will always be displayed, even if the value is not directly
takes a second parameter in the case of a volatile write. used by the function. The token representing the variable will be displayed using the
<emphasis role="bold">Special</emphasis> color, highlighting that the access is volatile
(See <xref linkend="DisplayTokenColor"/>).
<informalexample> <informalexample>
<programlisting> <programlisting>
X = read_volatile_2(SREG); X = <emphasis role="redtext">SREG</emphasis>; // Reading volatile SREG
write_volatile_1(DAT_mem_002b,0x20); <emphasis role="redtext">DAT_mem_002b</emphasis> = 0x20; // Writing volatile DAT
</programlisting> </programlisting>
</informalexample> </informalexample>
</para> </para>
@ -3982,8 +4112,10 @@
<listitem><para> <listitem><para>
Double-clicking a '{' or '}' token, causes the window to navigate to the <emphasis>matching</emphasis> brace Double-clicking a '{' or '}' token, causes the window to navigate to the <emphasis>matching</emphasis> brace
within the window. The cursor is set and the window view is adjusted if within the window. The cursor is set and the window view is adjusted if
necessary to ensure that the matching brace is visible. Braces may also be navigated via necessary to ensure that the matching brace is visible.
the keyboard. </para>
<para>
Braces may also be navigated <link linkend="GoToBrace">via the keyboard</link>.
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>
@ -4032,14 +4164,68 @@
</section> </section>
<section id="MenuActions"> <section id="MenuActions">
<title>Pop-up Menu Actions</title> <title>Pop-up Menu and Keyboard Actions</title>
<para> <para>
All the actions described in this section can be activated from the menu that pops up Almost all the actions described in this section can be activated from the menu that pops up
when right-clicking on a token within the Decompiler window. The pop-up menu is context sensitive and when right-clicking on a token within the Decompiler window. The pop-up menu is context sensitive and
the type of token in particular (see <xref linkend="DecompilerDisplay"/>) determines what actions are available. the type of token in particular (see <xref linkend="DecompilerDisplay"/>) determines what actions are available.
The token clicked provides a local context for the action and may be used to pinpoint the exact The token clicked provides a local context for the action and may be used to pinpoint the exact
variable or operation affected. variable or operation affected.
</para> </para>
<para>
Many of the actions have have a key binding, which, if it exists, will be listed in the pop-up menu.
If the key binding is used to activate the action, local context is determined by the current cursor
position. Key bindings can be reassigned from the
<link xlink:href="help/topics/Tool/ToolOptions_Dialog.htm#KeyBindings_Option">Key Bindings</link>
section of the <emphasis role="bold">Tool Options Dialog.</emphasis>
</para>
<sect2 id="ActionPointerOffset">
<title>Adjust Pointer Offset</title>
<para>
Create a pointer with an <emphasis>offset</emphasis> into its underlying data-type and apply it to the
selected variable.
</para>
<para>
The action is available on variable tokens that the Decompiler has already determined are pointers, and
is designed to create an <emphasis>offset pointer</emphasis>, which is a typedef with its
<emphasis>component offset</emphasis> attribute set (See <xref linkend="AttributeOffsetPointer"/>). It
brings up a dialog that allows the user to select:
<informalexample>
<itemizedlist mark='bullet'>
<listitem>An underlying data-type for the new pointer</listitem>
<listitem>A byte offset (relative to the start of the underlying data-type)</listitem>
<listitem>A name for the new pointer data-type</listitem>
</itemizedlist>
</informalexample>
If the Decompiler determines that the selected variable points into a known structure,
this information is used to prepopulate the dialog, with the structure used as the
underlying data-type.
</para>
<para>
Clicking OK in the dialog immediately creates the new pointer data-type and attaches it to the selected variable,
triggering a new decompilation. The annotation may reveal new field accesses or other markup associated with the
underlying data-type, which will be immediately visible once decompilation completes.
</para>
<para>
If the user selects the name of an offset pointer that already exists and its other properties match the dialog,
the existing pointer will be used to complete the action, rather than creating a new data-type. If an
unrelated data-type already exists with the selected name, the action cannot be completed and the dialog
will display a warning.
</para>
<note>
If the offset pointer already exists but its offset does <emphasis>not</emphasis> match the value specified
in the dialog, the user is given the option of changing the existing data-type's offset. Confirming
this change alters the existing data-type, which may affect analysis of other unrelated parts of
the program that use it.
</note>
<para>
Once an offset pointer exists, either by invoking this action or by creating it manually
(see <link xlink:href="help/topics/DataTypeManagerPlugin/data_type_manager_description.htm#Pointer_Typedef_Settings">Pointer-Typedef Settings</link>),
it can be applied to variables like any other data-type, either through the Listing window or using the
<xref linkend="ActionRetypeVariable"/> action in the Decompiler window.
</para>
</sect2>
<sect2 id="ActionAutoStructure"> <sect2 id="ActionAutoStructure">
<title>Auto Create Structure</title> <title>Auto Create Structure</title>
@ -4315,7 +4501,7 @@
Search for strings within the active window, in the current Decompiler output. Search for strings within the active window, in the current Decompiler output.
</para> </para>
<para> <para>
The command brings up a dialog where a search pattern can entered as a raw string or regular expression. The command brings up a dialog where a search pattern can be entered as a raw string or regular expression.
The search is performed directly on the text of the decompiled function, from the current cursor; forward The search is performed directly on the text of the decompiled function, from the current cursor; forward
each time the <emphasis role="bold">Next</emphasis> button is hit, or backward for the each time the <emphasis role="bold">Next</emphasis> button is hit, or backward for the
<emphasis role="bold">Previous</emphasis> button. Any match is highlighted in the window, <emphasis role="bold">Previous</emphasis> button. Any match is highlighted in the window,
@ -4323,13 +4509,48 @@
</para> </para>
</sect2> </sect2>
<sect2 id="ActionForceField">
<title>Force Field</title>
<para>
Force the Decompiler to assume a specific read or write to a variable, with a <emphasis>union</emphasis> data-type,
is referring to a user selected field.
</para>
<para>
A union data-type overlays multiple other data-type interpretations
(<emphasis role="bold">fields</emphasis>) on top of one variable; any one of which may be active at
a point where the variable is accessed. The Decompiler automatically selects which field it thinks is being
referenced (See <xref linkend="TypeUnion"/>). But this action allows the user to force
the Decompiler to use a particular field.
</para>
<para>
The cursor must be on the token currently representing the union field to be changed.
The action brings up a dialog with a drop-down menu of the possible fields that can be forced.
A field must be compatible with the selected access or it will not be listed in the menu. This usually
means that the data-type of the field must be the same size as the read or write being performed.
The menu option <code>(no field)</code> may also be available, which if selected, indicates that
the Decompiler should treat the read or write as accessing the union as a whole.
Its also possible that no other field is possible but the current one. In which case, the dialog will
display a warning message and contain no drop-down menu.
</para>
<para>
Selecting a menu option and clicking OK completes the action. Subsequent decompilation should show
the new field at the selected access point, and the data-type associated with the selected field will
likely propagate further across the function, possibly triggering substantial changes to the output.
</para>
<para>
If there is more than one access to the same variable with a union data-type,
each representative field token can be forced to a new field individually.
</para>
</sect2>
<sect2 id="GoToBrace"> <sect2 id="GoToBrace">
<title>Go To Next/Previous Brace</title> <title>Go To Next/Previous Brace</title>
<para> <para>
These actions are available from the keyboard. These actions are available from the keyboard, with no equivalent pop-up menu entry.
<emphasis role="bold">Shift-Open Bracket</emphasis> will go to the previous enclosing <emphasis role="bold">Shift-Open Bracket</emphasis> will go to the previous enclosing
open brace. <emphasis role="bold">Shift-Close Bracket</emphasis> will go to the open brace. <emphasis role="bold">Shift-Close Bracket</emphasis> will go to the
next enclosing closing brace. These key bindings can be changed via the tool options. next enclosing closing brace. These key bindings can be changed via the
<link xlink:href="help/topics/Tool/ToolOptions_Dialog.htm#KeyBindings_Option">Tool Options Dialog</link>.
</para> </para>
<para> <para>
Paired braces can also be navigated by double-clicking. Paired braces can also be navigated by double-clicking.

View file

@ -96,7 +96,7 @@
<tocdef id="UndefinedFunction" sortgroup="d" text="Undefined Functions" target="help/topics/DecompilePlugin/DecompilerWindow.html#UndefinedFunction"/> <tocdef id="UndefinedFunction" sortgroup="d" text="Undefined Functions" target="help/topics/DecompilePlugin/DecompilerWindow.html#UndefinedFunction"/>
<tocdef id="ToolBar" sortgroup="e" text="Tool Bar" target="help/topics/DecompilePlugin/DecompilerWindow.html#ToolBar"/> <tocdef id="ToolBar" sortgroup="e" text="Tool Bar" target="help/topics/DecompilePlugin/DecompilerWindow.html#ToolBar"/>
<tocdef id="MouseActions" sortgroup="f" text="Mouse Actions" target="help/topics/DecompilePlugin/DecompilerWindow.html#MouseActions"/> <tocdef id="MouseActions" sortgroup="f" text="Mouse Actions" target="help/topics/DecompilePlugin/DecompilerWindow.html#MouseActions"/>
<tocdef id="MenuActions" sortgroup="g" text="Pop-up Menu Actions" target="help/topics/DecompilePlugin/DecompilerWindow.html#MenuActions"/> <tocdef id="MenuActions" sortgroup="g" text="Pop-up Menu and Keyboard Actions" target="help/topics/DecompilePlugin/DecompilerWindow.html#MenuActions"/>
</tocdef> </tocdef>
</tocdef> </tocdef>
</tocref> </tocref>

View file

@ -24,4 +24,4 @@ dd { margin-bottom: 20px; }
dd p { margin-top: 5px; margin-left: 10px; } dd p { margin-top: 5px; margin-left: 10px; }
span.term { font-family:times new roman; font-size:14pt; font-weight:bold; } span.term { font-family:times new roman; font-size:14pt; font-weight:bold; }
span.code { font-weight: bold; font-family: courier new; font-size: 14pt; color:#000000; } span.code { font-weight: bold; font-family: courier new; font-size: 14pt; color:#000000; }
span.redtext { color:#CC0033; }

View file

@ -724,6 +724,150 @@
<p> <p>
</p> </p>
</div> </div>
<div class="sect4">
<div class="titlepage"><div><div><h5 class="title">
<a name="TypeUnion"></a>Unions</h5></div></div></div>
<p>
Unions data-types are fully supported. The Decompiler does not automatically infer unions
when analyzing a function; it propagates them into the function from explicitly
annotated sources, like input parameters or global variables.
</p>
<p>
A union data-type, similarly to a structure, is made up of component data-types
called <span class="emphasis"><em>fields</em></span>. But unlike a structure, a union's fields all share the same underlying
storage. When the union is applied to a variable, each field potentially describes the whole variable.
At any given point where the variable is read or written, a different field may be in effect, even if the
underlying data hasn't changed. The decompiler attempts to infer the particular field by following data-flow
to or from the point of use to determine which field best aligns with the specific operations being applied to the
variable. The name of this recovered field is then printed in Decompiler output using syntax similar to that
used for structure fields.
</p>
<p>
Depending on the number and variety of fields within the union, it may not be possible
to fully distinguish which field is being used in a specific context. In this situation,
the Decompiler chooses the first field from the list of best matches. The user has the
option of changing this choice with the <a class="xref" href="DecompilerWindow.html#ActionForceField" title="Force Field">Force Field</a> action.
</p>
</div>
<div class="sect4">
<div class="titlepage"><div><div><h5 class="title">
<a name="TypeTypedef"></a>Typedefs</h5></div></div></div>
<p>
Typedef data-types are fully supported. The Decompiler does not automatically infer typedefs
when analyzing a function; it propagates them into the function from explicitly annotated sources.
</p>
<p>
A <span class="bold"><strong>typedef</strong></span> is copy of another data-type but with an alternate name.
In most cases it can be used interchangeably with the data-type it copies.
In general, the Decompiler treats a typedef as a distinct data-type, and it will maintain its identify
when it is assigned to variables and is propagated through data-flow.
</p>
<p>
Ghidra supports a specific set of attributes that can be placed directly on a typedef
that then distinguish it from the data-type it copies. This allows Ghidra to support some
non-standard data-types, although the typedef and its copy are no longer interchangeable.
The decompiler supports the following typedef properties:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: none; ">
<li class="listitem" style="list-style-type: none">Component Offset - See <a class="xref" href="DecompilerAnnotations.html#AttributeOffsetPointer" title="Offset Pointers">Offset Pointers</a>
</li>
<li class="listitem" style="list-style-type: none">Address Space - See <a class="xref" href="DecompilerAnnotations.html#AttributeAddressPointer" title="Address Space Pointers">Address Space Pointers</a>
</li>
</ul></div>
<p>
</p>
</div>
</div>
<div class="sect3">
<div class="titlepage"><div><div><h4 class="title">
<a name="AnnotePointerAttributes"></a>Pointer Attributes</h4></div></div></div>
<p>
The Decompiler supports some specialized attributes that can be applied to pointer data-types, like offsets
and address spaces (See below). Ghidra implements these attributes on top of <span class="emphasis"><em>typedef</em></span> data-types only. In
order to add attributes to pointers, a typedef of the underlying pointer data-type must be created first.
Attributes can then be placed directly on the typedef from the Data Type Manager window
(See <a class="ulink" href="help/topics/DataTypeManagerPlugin/data_type_manager_description.htm#Pointer_Typedef_Settings" target="_top">Pointer-Typedef Settings</a>).
</p>
<div class="sect4">
<div class="titlepage"><div><div><h5 class="title">
<a name="AttributeOffsetPointer"></a>Offset Pointers</h5></div></div></div>
<p>
An <span class="bold"><strong>offset pointer</strong></span> points at a fixed offset relative to the start of its
underlying data-type. Typically the underlying data-type is a structure and the pointer points at a
specific field in the interior of the structure. But in general, the underlying data-type can be anything,
and the offset can point anywhere relative to that data-type, including either before or after.
</p>
<p>
An offset pointer is defined with all the same properties of a normal pointer. It has an underlying
data-type and a size. On top of this an <span class="bold"><strong>offset</strong></span> is specified
as an integer attribute on the pointer (typedef). This is the number of bytes that need to be
added to the start of the underlying data-type to obtain the address actually being pointed at.
</p>
<p>
Because the <span class="emphasis"><em>underlying</em></span> data-type does not start directly at the address
contained in the offset pointer, one can also refer to the offset pointer's
<span class="bold"><strong>direct</strong></span> data-type, i.e. the data-type that <span class="emphasis"><em>is</em></span>
directly at the address contained in the pointer. If the pointer's offset is positive (and small),
the direct data-type will generally be that of a field of the <span class="emphasis"><em>underlying</em></span>
data-type. If the offset is bigger than the size of the underlying data-type or is negative,
the direct data-type will be <span class="emphasis"><em>undefined</em></span>.
</p>
<p>
Offset pointers occur in code where the compiler has maintained knowledge of the position of
an underlying data-type relative to a pointer, even if the pointer no longer points directly at the data-type.
Because of this, the code may still access fields of the underlying data-type through the pointer.
Annotating a variable with an offset pointer allows the Decompiler to recover these accesses.
</p>
<p>
Within the Decompiler's output, the token <code class="code">ADJ</code> is used to indicate that the code is
accessing the underlying data-type through the offset pointer. The token uses functional syntax
to indicate the particular offset pointer. Then, once the <code class="code">ADJ</code> token is
applied, additional pointer syntax is used, i.e. <code class="code">-&gt;</code>, to indicate what part
of the underlying data-type is being accessed.
</p>
<div class="informalexample">
<pre class="programlisting">
ADJ(structoffptr)-&gt;field1 = 2; // Accessing the underlying structure's field
iVar1 = *ADJ(intoffptr); // Accessing the underlying integer data-type
ADJ(arrayoffptr)[4] = iVar2; // Accessing the underlying array
</pre>
</div>
<p>
If the offset pointer appears in Decompiler output without the <code class="code">ADJ</code> token being
applied, it is being treated as if it were a normal pointer to its direct
data-type. This generally indicates the pointer is being used to access data outside the
underlying data-type.
</p>
</div>
<div class="sect4">
<div class="titlepage"><div><div><h5 class="title">
<a name="AttributeAddressPointer"></a>Address Space Pointers</h5></div></div></div>
<p>
An <span class="bold"><strong>address space pointer</strong></span> is a normal pointer data-type with a specific
address space associated to it (See <a class="xref" href="DecompilerConcepts.html#ConceptAddressSpace" title="Address Space">Address Space</a>). Its created by setting
the Address Space attribute on a typedef of a pointer. The attribute value is the name of the specific
address space.
</p>
<p>
Address space pointers are useful, when a program architecture supports more than one address space
containing addressable memory, such as separate <code class="code">code</code> and <code class="code">data</code> address spaces.
For a program and a specific section of its code that manipulates a pointer, it may not be easy to determine
which address space is being referred to. Address space pointers provide an additional annotation mechanism
to help the decompiler identify the correct address space for a pointer in context.
</p>
<p>
The Decompiler will automatically propagate an address space pointer data-type from parameters and
other annotated variables associated with a function. Any constant that the pointer reaches via propagation
is assumed to point into the address space associated with the pointer. The correct symbol can then
be looked up, further informing the Decompiler output.
</p>
</div>
</div> </div>
<div class="sect3"> <div class="sect3">
@ -1207,18 +1351,20 @@
<p> <p>
The <span class="bold"><strong>volatile</strong></span> mutability setting indicates that values within The <span class="bold"><strong>volatile</strong></span> mutability setting indicates that values within
the memory region may change unexpectedly, even if the code currently executing does not directly the memory region may change unexpectedly, even if the code currently executing does not directly
write to it. If a volatile variable is accessed in a function being analyzed by the Decompiler, write to it. Accessing a variable within a volatile region, either reading or writing, can have other
each specific access is replaced with a built-in function call, which prevents constant propagation side-effects on the machine state, and it cannot in general be treated as normal variable.
and other transforms across the access. The built-in functions are named based on If a volatile variable is accessed in a function being analyzed by the Decompiler,
whether the access is a <span class="emphasis"><em>read</em></span> or <span class="emphasis"><em>write</em></span> and on the <span class="emphasis"><em>size</em></span> each access is expressed as a copy statement on its own line, separated from other expressions,
of the access. Within the Decompiler output, the first parameter to a built-in function is a symbol so that the its position within the code and any sequence of accesses is clearly indicated.
indicating the volatile variable. The function returns a value in the case of a volatile read or Any access, either read or write, will always be displayed, even if the value is not directly
takes a second parameter in the case of a volatile write. used by the function. The token representing the variable will be displayed using the
<span class="bold"><strong>Special</strong></span> color, highlighting that the access is volatile
(See <a class="xref" href="DecompilerOptions.html#DisplayTokenColor"><span class="bold"><strong>Color for &lt;token&gt;</strong></span></a>).
</p> </p>
<div class="informalexample"> <div class="informalexample">
<pre class="programlisting"> <pre class="programlisting">
X = read_volatile_2(SREG); X = <span class="redtext">SREG</span>; // Reading volatile SREG
write_volatile_1(DAT_mem_002b,0x20); <span class="redtext">DAT_mem_002b</span> = 0x20; // Writing volatile DAT
</pre> </pre>
</div> </div>
<p> <p>

View file

@ -364,6 +364,8 @@
<span class="bold"><strong>Types</strong></span> - names of data-types in variable declarations and casts</li> <span class="bold"><strong>Types</strong></span> - names of data-types in variable declarations and casts</li>
<li class="listitem" style="list-style-type: disc"> <li class="listitem" style="list-style-type: disc">
<span class="bold"><strong>Variables</strong></span> - names of local variables</li> <span class="bold"><strong>Variables</strong></span> - names of local variables</li>
<li class="listitem" style="list-style-type: disc">
<span class="bold"><strong>Special</strong></span> - volatile variables and other special symbols</li>
</ul></div> </ul></div>
</div> </div>
<p> <p>

View file

@ -18,7 +18,7 @@
function in the Code Browser, then select the function in the Code Browser, then select the
<span class="guiicon"> <span class="guiicon">
<span class="inlinemediaobject"><img src="images/decompileFunction.gif" width="16" height="16"></span> <span class="inlinemediaobject"><img src="images/decompileFunction.gif" width="16" height="16"></span>
</span><EFBFBD>icon from the tool bar, or the </span> icon from the tool bar, or the
<span class="bold"><strong>Decompile</strong></span> option from the <span class="bold"><strong>Decompile</strong></span> option from the
<span class="bold"><strong>Window</strong></span> menu in the tool. <span class="bold"><strong>Window</strong></span> menu in the tool.
</p> </p>
@ -91,7 +91,7 @@
Initially pressing Initially pressing
<span class="guiicon"> <span class="guiicon">
<span class="inlinemediaobject"><img src="images/decompileFunction.gif" width="16" height="16"></span> <span class="inlinemediaobject"><img src="images/decompileFunction.gif" width="16" height="16"></span>
</span><EFBFBD>or selecting </span> or selecting
<span class="bold"><strong>Decompile</strong></span> from the <span class="bold"><strong>Window</strong></span> menu in the tool <span class="bold"><strong>Decompile</strong></span> from the <span class="bold"><strong>Window</strong></span> menu in the tool
brings up the <span class="emphasis"><em>main</em></span> window. The main window always displays the function brings up the <span class="emphasis"><em>main</em></span> window. The main window always displays the function
at the <span class="emphasis"><em>current address</em></span> within the Code Browser and follows as the user navigates at the <span class="emphasis"><em>current address</em></span> within the Code Browser and follows as the user navigates
@ -153,7 +153,7 @@
Pressing the Pressing the
<span class="guiicon"> <span class="guiicon">
<span class="inlinemediaobject"><img src="images/camera-photo.png" width="16" height="16"></span> <span class="inlinemediaobject"><img src="images/camera-photo.png" width="16" height="16"></span>
</span><EFBFBD>icon </span> icon
in any Decompiler window's toolbar causes a <span class="emphasis"><em>Snapshot</em></span> window in any Decompiler window's toolbar causes a <span class="emphasis"><em>Snapshot</em></span> window
to be created, which shows decompilation of the same function. to be created, which shows decompilation of the same function.
Unlike the <span class="emphasis"><em>main</em></span> window however, the <span class="emphasis"><em>Snapshot</em></span> window Unlike the <span class="emphasis"><em>main</em></span> window however, the <span class="emphasis"><em>Snapshot</em></span> window
@ -240,7 +240,7 @@
<p> <p>
<span class="guiicon"> <span class="guiicon">
<span class="inlinemediaobject"><img src="images/page_edit.png" width="16" height="16"></span> <span class="inlinemediaobject"><img src="images/page_edit.png" width="16" height="16"></span>
</span><EFBFBD>- button </span> - button
</p> </p>
<p> <p>
Exports the decompiled result of the current function to a file. A file chooser Exports the decompiled result of the current function to a file. A file chooser
@ -265,7 +265,7 @@
<p> <p>
<span class="guiicon"> <span class="guiicon">
<span class="inlinemediaobject"><img src="images/camera-photo.png" width="16" height="16"></span> <span class="inlinemediaobject"><img src="images/camera-photo.png" width="16" height="16"></span>
</span><EFBFBD>- button </span> - button
</p> </p>
<p> <p>
Creates a new <span class="emphasis"><em>Snapshot</em></span> window. The <span class="emphasis"><em>Snapshot</em></span> window Creates a new <span class="emphasis"><em>Snapshot</em></span> window. The <span class="emphasis"><em>Snapshot</em></span> window
@ -282,7 +282,7 @@
<p> <p>
<span class="guiicon"> <span class="guiicon">
<span class="inlinemediaobject"><img src="images/reload3.png" width="16" height="16"></span> <span class="inlinemediaobject"><img src="images/reload3.png" width="16" height="16"></span>
</span><EFBFBD>- button </span> - button
</p> </p>
<p> <p>
Triggers a re-decompilation of the current function displayed in the window. Triggers a re-decompilation of the current function displayed in the window.
@ -310,7 +310,7 @@
<p> <p>
<span class="guiicon"> <span class="guiicon">
<span class="inlinemediaobject"><img src="images/page_white_copy.png" width="16" height="16"></span> <span class="inlinemediaobject"><img src="images/page_white_copy.png" width="16" height="16"></span>
</span><EFBFBD>- button </span> - button
</p> </p>
<p> <p>
Copies the currently selected text in the Decompiler window to the clipboard. Copies the currently selected text in the Decompiler window to the clipboard.
@ -349,12 +349,15 @@
window tool/title bar. window tool/title bar.
</p> </p>
<p> <p>
Generate an data flow graph based upon the results in the active Decompiler window, Generate a data flow graph based upon the results in the active Decompiler window,
and render it using the current Graph Service. and render it using the current Graph Service.
</p> </p>
<div class="titlepage"><div><div><h3 class="title"> </div>
<a name="ControlFlowGraph"></a>Graph Control Flow</h3></div></div></div>
</div> <div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="ControlFlowGraph"></a>Graph Control Flow</h3></div></div></div>
<p> <p>
This action is located in the drop-down menu on the right side of the Decompiler This action is located in the drop-down menu on the right side of the Decompiler
window tool/title bar. window tool/title bar.
@ -363,7 +366,6 @@
Generate a control flow graph based upon the results in the active Decompiler window, Generate a control flow graph based upon the results in the active Decompiler window,
and render it using the current Graph Service. and render it using the current Graph Service.
</p> </p>
</div> </div>
</div> </div>
@ -447,16 +449,16 @@
necessary to ensure that the target is visible. necessary to ensure that the target is visible.
</p></dd> </p></dd>
<dt><span class="term"><span class="bold"><strong>Braces</strong></span></span></dt> <dt><span class="term"><span class="bold"><strong>Braces</strong></span></span></dt>
<dd><p> <dd>
<p>
Double-clicking a '{' or '}' token, causes the window to navigate to the <span class="emphasis"><em>matching</em></span> brace Double-clicking a '{' or '}' token, causes the window to navigate to the <span class="emphasis"><em>matching</em></span> brace
within the window. The cursor is set and the window view is adjusted if within the window. The cursor is set and the window view is adjusted if
necessary to ensure that the matching brace is visible. necessary to ensure that the matching brace is visible.
</p>
<p>
Braces may also be navigated <a class="link" href="DecompilerWindow.html#GoToBrace" title="Go To Next/Previous Brace">via the keyboard</a>.
</p> </p>
<p> </dd>
Braces may also be navigated
<a class="xref" href="DecompilerWindow.html#GoToBrace" title="Go To Brace">via the keyboard</a>.
</p>
</dd>
</dl></div> </dl></div>
</div> </div>
<p> <p>
@ -511,15 +513,79 @@
<div class="section"> <div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both"> <div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="MenuActions"></a>Pop-up Menu Actions</h2></div></div></div> <a name="MenuActions"></a>Pop-up Menu and Keyboard Actions</h2></div></div></div>
<p> <p>
All the actions described in this section can be activated from the menu that pops up Almost all the actions described in this section can be activated from the menu that pops up
when right-clicking on a token within the Decompiler window. The pop-up menu is context sensitive and when right-clicking on a token within the Decompiler window. The pop-up menu is context sensitive and
the type of token in particular (see <a class="xref" href="DecompilerWindow.html#DecompilerDisplay" title="Display">Display</a>) determines what actions are available. the type of token in particular (see <a class="xref" href="DecompilerWindow.html#DecompilerDisplay" title="Display">Display</a>) determines what actions are available.
The token clicked provides a local context for the action and may be used to pinpoint the exact The token clicked provides a local context for the action and may be used to pinpoint the exact
variable or operation affected. variable or operation affected.
</p> </p>
<p>
Many of the actions have have a key binding, which, if it exists, will be listed in the pop-up menu.
If the key binding is used to activate the action, local context is determined by the current cursor
position. Key bindings can be reassigned from the
<a class="ulink" href="help/topics/Tool/ToolOptions_Dialog.htm#KeyBindings_Option" target="_top">Key Bindings</a>
section of the <span class="bold"><strong>Tool Options Dialog.</strong></span>
</p>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="ActionPointerOffset"></a>Adjust Pointer Offset</h3></div></div></div>
<p>
Create a pointer with an <span class="emphasis"><em>offset</em></span> into its underlying data-type and apply it to the
selected variable.
</p>
<p>
The action is available on variable tokens that the Decompiler has already determined are pointers, and
is designed to create an <span class="emphasis"><em>offset pointer</em></span>, which is a typedef with its
<span class="emphasis"><em>component offset</em></span> attribute set (See <a class="xref" href="DecompilerAnnotations.html#AttributeOffsetPointer" title="Offset Pointers">Offset Pointers</a>). It
brings up a dialog that allows the user to select:
</p>
<div class="informalexample">
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: bullet; ">
<li class="listitem" style="list-style-type: disc">An underlying data-type for the new pointer</li>
<li class="listitem" style="list-style-type: disc">A byte offset (relative to the start of the underlying data-type)</li>
<li class="listitem" style="list-style-type: disc">A name for the new pointer data-type</li>
</ul></div>
</div>
<p>
If the Decompiler determines that the selected variable points into a known structure,
this information is used to prepopulate the dialog, with the structure used as the
underlying data-type.
</p>
<p>
Clicking OK in the dialog immediately creates the new pointer data-type and attaches it to the selected variable,
triggering a new decompilation. The annotation may reveal new field accesses or other markup associated with the
underlying data-type, which will be immediately visible once decompilation completes.
</p>
<p>
If the user selects the name of an offset pointer that already exists and its other properties match the dialog,
the existing pointer will be used to complete the action, rather than creating a new data-type. If an
unrelated data-type already exists with the selected name, the action cannot be completed and the dialog
will display a warning.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../shared/note.png"></td>
<th align="left"></th>
</tr>
<tr><td align="left" valign="top">
If the offset pointer already exists but its offset does <span class="emphasis"><em>not</em></span> match the value specified
in the dialog, the user is given the option of changing the existing data-type's offset. Confirming
this change alters the existing data-type, which may affect analysis of other unrelated parts of
the program that use it.
</td></tr>
</table></div>
<p>
Once an offset pointer exists, either by invoking this action or by creating it manually
(see <a class="ulink" href="help/topics/DataTypeManagerPlugin/data_type_manager_description.htm#Pointer_Typedef_Settings" target="_top">Pointer-Typedef Settings</a>),
it can be applied to variables like any other data-type, either through the Listing window or using the
<a class="xref" href="DecompilerWindow.html#ActionRetypeVariable" title="Retype Variable">Retype Variable</a> action in the Decompiler window.
</p>
</div>
<div class="sect2"> <div class="sect2">
<div class="titlepage"><div><div><h3 class="title"> <div class="titlepage"><div><div><h3 class="title">
@ -804,7 +870,7 @@
Search for strings within the active window, in the current Decompiler output. Search for strings within the active window, in the current Decompiler output.
</p> </p>
<p> <p>
The command brings up a dialog where a search pattern can entered as a raw string or regular expression. The command brings up a dialog where a search pattern can be entered as a raw string or regular expression.
The search is performed directly on the text of the decompiled function, from the current cursor; forward The search is performed directly on the text of the decompiled function, from the current cursor; forward
each time the <span class="bold"><strong>Next</strong></span> button is hit, or backward for the each time the <span class="bold"><strong>Next</strong></span> button is hit, or backward for the
<span class="bold"><strong>Previous</strong></span> button. Any match is highlighted in the window, <span class="bold"><strong>Previous</strong></span> button. Any match is highlighted in the window,
@ -812,24 +878,58 @@
</p> </p>
</div> </div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="ActionForceField"></a>Force Field</h3></div></div></div>
<p>
Force the Decompiler to assume a specific read or write to a variable, with a <span class="emphasis"><em>union</em></span> data-type,
is referring to a user selected field.
</p>
<p>
A union data-type overlays multiple other data-type interpretations
(<span class="bold"><strong>fields</strong></span>) on top of one variable; any one of which may be active at
a point where the variable is accessed. The Decompiler automatically selects which field it thinks is being
referenced (See <a class="xref" href="DecompilerAnnotations.html#TypeUnion" title="Unions">Unions</a>). But this action allows the user to force
the Decompiler to use a particular field.
</p>
<p>
The cursor must be on the token currently representing the union field to be changed.
The action brings up a dialog with a drop-down menu of the possible fields that can be forced.
A field must be compatible with the selected access or it will not be listed in the menu. This usually
means that the data-type of the field must be the same size as the read or write being performed.
The menu option <code class="code">(no field)</code> may also be available, which if selected, indicates that
the Decompiler should treat the read or write as accessing the union as a whole.
Its also possible that no other field is possible but the current one. In which case, the dialog will
display a warning message and contain no drop-down menu.
</p>
<p>
Selecting a menu option and clicking OK completes the action. Subsequent decompilation should show
the new field at the selected access point, and the data-type associated with the selected field will
likely propagate further across the function, possibly triggering substantial changes to the output.
</p>
<p>
If there is more than one access to the same variable with a union data-type,
each representative field token can be forced to a new field individually.
</p>
</div>
<div class="sect2"> <div class="sect2">
<div class="titlepage"><div><div><h3 class="title"> <div class="titlepage"><div><div><h3 class="title">
<a name="GoToBrace"></a>Go To Next/Previous Brace</h3></div></div></div> <a name="GoToBrace"></a>Go To Next/Previous Brace</h3></div></div></div>
<p> <p>
These actions are available from the keyboard. These actions are available from the keyboard, with no equivalent pop-up menu entry.
<span class="bold"><strong>Shift-Open Bracket</strong></span> will go to the previous enclosing <span class="bold"><strong>Shift-Open Bracket</strong></span> will go to the previous enclosing
open brace. <span class="bold"><strong>Shift-Close Bracket</strong></span> will go to the open brace. <span class="bold"><strong>Shift-Close Bracket</strong></span> will go to the
next enclosing closing brace. These key bindings can be changed via the tool options. next enclosing closing brace. These key bindings can be changed via the
<a class="ulink" href="help/topics/Tool/ToolOptions_Dialog.htm#KeyBindings_Option" target="_top">Tool Options Dialog</a>.
</p> </p>
<p> <p>
Paired braces can also be navigated by double-clicking. Paired braces can also be navigated by double-clicking.
</p> </p>
</div> </div>
<div class="sect2"> <div class="sect2">
<div class="titlepage"><div><div><h3 class="title"> <div class="titlepage"><div><div><h3 class="title">
<a name="ActionHighlight"></a>Highlight</h3></div></div></div> <a name="ActionHighlight"></a>Highlight</h3></div></div></div>
@ -1012,8 +1112,8 @@
<p> <p>
Display locations in the Program that reference the <span class="bold"><strong>function</strong></span> or Display locations in the Program that reference the <span class="bold"><strong>function</strong></span> or
<span class="bold"><strong>global variable</strong></span> <span class="bold"><strong>global variable</strong></span> associated with the token under the cursor.
associated with the token under the cursor. Results are collected in a Results are collected in a
<a class="ulink" href="help/topics/LocationReferencesPlugin/Location_References.html" target="_top">Location References Dialog</a>, <a class="ulink" href="help/topics/LocationReferencesPlugin/Location_References.html" target="_top">Location References Dialog</a>,
which displays a row for each reference with its address and other context. which displays a row for each reference with its address and other context.
</p> </p>
@ -1024,7 +1124,7 @@
</div> </div>
<div class="sect3"> <div class="sect3">
<div class="titlepage"><div><div><h4 class="title"> <div class="titlepage"><div><div><h4 class="title">
<a name="ActionShowReferences"></a>Show References to &lt;address&gt</h4></div></div></div> <a name="ActionShowReferences"></a>Show References to &lt;address&gt;</h4></div></div></div>
<p> <p>
Display locations in the Program that reference the <span class="bold"><strong>address</strong></span> Display locations in the Program that reference the <span class="bold"><strong>address</strong></span>
@ -1073,7 +1173,6 @@
</p> </p>
</div> </div>
<div class="sect2"> <div class="sect2">
<div class="titlepage"><div><div><h3 class="title"> <div class="titlepage"><div><div><h3 class="title">
<a name="ActionRemoveLabel"></a>Remove Label</h3></div></div></div> <a name="ActionRemoveLabel"></a>Remove Label</h3></div></div></div>
@ -1082,9 +1181,9 @@
Remove the label corresponding to the token under the cursor. Remove the label corresponding to the token under the cursor.
</p> </p>
<p> <p>
A label can be removed by triggering this action while the corresponding label token is A label can be removed by triggering this action while the corresponding label token is
under the cursor. For more on removing labels, see under the cursor. For more on removing labels, see
<a class="ulink" href="help/topics/LabelMgrPlugin/Labels.htm#Remove_Label" target="_top">Removing a Label</a>. <a class="ulink" href="help/topics/LabelMgrPlugin/Labels.htm#Remove_Label" target="_top">Removing a Label</a>.
</p> </p>
<p> <p>
The change will be immediately visible across all references to the label The change will be immediately visible across all references to the label
@ -1092,7 +1191,6 @@
</p> </p>
</div> </div>
<div class="sect2"> <div class="sect2">
<div class="titlepage"><div><div><h3 class="title"> <div class="titlepage"><div><div><h3 class="title">
<a name="ActionRenameFunction"></a>Rename Function</h3></div></div></div> <a name="ActionRenameFunction"></a>Rename Function</h3></div></div></div>

View file

@ -26,6 +26,7 @@ import docking.widgets.OptionDialog;
import docking.widgets.label.GLabel; import docking.widgets.label.GLabel;
import ghidra.app.decompiler.ClangToken; import ghidra.app.decompiler.ClangToken;
import ghidra.app.plugin.core.decompile.DecompilerActionContext; import ghidra.app.plugin.core.decompile.DecompilerActionContext;
import ghidra.app.util.HelpTopics;
import ghidra.app.util.datatype.DataTypeSelectionDialog; import ghidra.app.util.datatype.DataTypeSelectionDialog;
import ghidra.app.util.datatype.DataTypeSelectionEditor; import ghidra.app.util.datatype.DataTypeSelectionEditor;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
@ -34,8 +35,7 @@ import ghidra.program.model.data.*;
import ghidra.program.model.listing.Function; import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.model.pcode.*; import ghidra.program.model.pcode.*;
import ghidra.util.Msg; import ghidra.util.*;
import ghidra.util.UndefinedFunction;
import ghidra.util.data.DataTypeParser; import ghidra.util.data.DataTypeParser;
import ghidra.util.layout.VerticalLayout; import ghidra.util.layout.VerticalLayout;
@ -343,7 +343,7 @@ public class CreatePointerRelative extends RetypeLocalAction {
public CreatePointerRelative() { public CreatePointerRelative() {
super("Create Relative Pointer"); super("Create Relative Pointer");
// setHelpLocation(new HelpLocation(HelpTopics.DECOMPILER, "ActionRetypeVariable")); setHelpLocation(new HelpLocation(HelpTopics.DECOMPILER, "ActionPointerOffset"));
setPopupMenuData(new MenuData(new String[] { "Adjust Pointer Offset" }, "Decompile")); setPopupMenuData(new MenuData(new String[] { "Adjust Pointer Offset" }, "Decompile"));
// setKeyBindingData(new KeyBindingData(KeyEvent.VK_L, InputEvent.CTRL_DOWN_MASK)); // setKeyBindingData(new KeyBindingData(KeyEvent.VK_L, InputEvent.CTRL_DOWN_MASK));
} }

View file

@ -23,14 +23,14 @@ import docking.widgets.OptionDialog;
import ghidra.app.decompiler.ClangFieldToken; import ghidra.app.decompiler.ClangFieldToken;
import ghidra.app.decompiler.ClangToken; import ghidra.app.decompiler.ClangToken;
import ghidra.app.plugin.core.decompile.DecompilerActionContext; import ghidra.app.plugin.core.decompile.DecompilerActionContext;
import ghidra.app.util.HelpTopics;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.data.*; import ghidra.program.model.data.*;
import ghidra.program.model.listing.Function; import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.model.pcode.*; import ghidra.program.model.pcode.*;
import ghidra.program.model.symbol.SourceType; import ghidra.program.model.symbol.SourceType;
import ghidra.util.Msg; import ghidra.util.*;
import ghidra.util.UndefinedFunction;
import ghidra.util.exception.DuplicateNameException; import ghidra.util.exception.DuplicateNameException;
import ghidra.util.exception.InvalidInputException; import ghidra.util.exception.InvalidInputException;
@ -50,7 +50,7 @@ public class ForceUnionAction extends AbstractDecompilerAction {
public ForceUnionAction() { public ForceUnionAction() {
super("Force Union Field"); super("Force Union Field");
// setHelpLocation(new HelpLocation(HelpTopics.DECOMPILER, "ActionRenameField")); setHelpLocation(new HelpLocation(HelpTopics.DECOMPILER, "ActionForceField"));
setPopupMenuData(new MenuData(new String[] { "Force Field" }, "Decompile")); setPopupMenuData(new MenuData(new String[] { "Force Field" }, "Decompile"));
// setKeyBindingData(new KeyBindingData(KeyEvent.VK_L, 0)); // setKeyBindingData(new KeyBindingData(KeyEvent.VK_L, 0));
} }