mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
GP-943 Added support for zero-length arrays and
zero-length components. NOTE: We still never return 0 for DataType.getLength(). Added DataType.isZeroLength().
This commit is contained in:
parent
579e3bacf7
commit
cfdec26da4
188 changed files with 7968 additions and 6645 deletions
|
@ -306,7 +306,7 @@ public class DataTypeEditorsScreenShots extends GhidraScreenShotGenerator {
|
|||
struct.add(new ByteDataType(), "myByteElement2", "another non-packed byte");
|
||||
struct.add(new DWordDataType(), "myDWordElement", "non-packed dword");
|
||||
if (includeFlexArray) {
|
||||
struct.setFlexibleArrayComponent(CharDataType.dataType, "flex",
|
||||
struct.add(new ArrayDataType(CharDataType.dataType, 0, -1), "flex",
|
||||
"unsized flexible array");
|
||||
}
|
||||
struct.clearComponent(1);
|
||||
|
@ -341,7 +341,7 @@ public class DataTypeEditorsScreenShots extends GhidraScreenShotGenerator {
|
|||
struct.add(new ByteDataType(), "myByteElement2", "alignment 1");
|
||||
struct.add(new DWordDataType(), "myDWordElement", "alignment 4");
|
||||
if (includeBitFieldsAndFlexArray) {
|
||||
struct.setFlexibleArrayComponent(CharDataType.dataType, "flex",
|
||||
struct.add(new ArrayDataType(CharDataType.dataType, 0, -1), "flex",
|
||||
"unsized flexible array");
|
||||
}
|
||||
struct.clearComponent(1);
|
||||
|
|
|
@ -0,0 +1,181 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.program.database.data;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.program.database.ProgramBuilder;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.listing.*;
|
||||
|
||||
public class DataDBTest extends AbstractGenericTest {
|
||||
|
||||
private Program program;
|
||||
private Listing listing;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
program = buildProgram();
|
||||
listing = program.getListing();
|
||||
program.startTransaction("TEST");
|
||||
|
||||
/**
|
||||
* /structA
|
||||
* pack(disabled)
|
||||
* Structure structA {
|
||||
* 0 int 4 a0 ""
|
||||
* 4 char[0] 0 az ""
|
||||
* 5 byte 1 a1 ""
|
||||
* 6 char[0] 0 aflex ""
|
||||
* }
|
||||
* Size = 6 Actual Alignment = 1
|
||||
*/
|
||||
Structure structA = new StructureDataType("structA", 0);
|
||||
structA.add(IntegerDataType.dataType, "a0", null);
|
||||
structA.add(new ArrayDataType(CharDataType.dataType, 0, -1), "az", null);
|
||||
structA.add(DataType.DEFAULT);
|
||||
structA.add(ByteDataType.dataType, "a1", null);
|
||||
structA.add(new ArrayDataType(IntegerDataType.dataType, 0, -1), "aflex", null);
|
||||
|
||||
/**
|
||||
* /structB
|
||||
* pack()
|
||||
* Structure structB {
|
||||
* 0 short 2 b0 ""
|
||||
* 4 int:0(0) 0 ""
|
||||
* 4 byte[0] 0 bfs ""
|
||||
* 4 int:4(0) 1 bf1 ""
|
||||
* 4 int:6(4) 2 bf2 ""
|
||||
* 5 int:2(2) 1 bf3 ""
|
||||
* 6 structA 6 b1 ""
|
||||
* }
|
||||
* Size = 12 Actual Alignment = 4
|
||||
*/
|
||||
Structure structB = new StructureDataType("structB", 0);
|
||||
structB.setPackingEnabled(true);
|
||||
structB.add(ShortDataType.dataType, "b0", null);
|
||||
structB.addBitField(IntegerDataType.dataType, 0, null, null); // force integer alignment
|
||||
structB.add(new ArrayDataType(ByteDataType.dataType, 0, -1), "bfs", null);
|
||||
structB.addBitField(IntegerDataType.dataType, 4, "bf1", null);
|
||||
structB.addBitField(IntegerDataType.dataType, 6, "bf2", null);
|
||||
structB.addBitField(IntegerDataType.dataType, 2, "bf3", null);
|
||||
structB.add(structA, "b1", null);
|
||||
|
||||
/**
|
||||
* /structC
|
||||
* pack()
|
||||
* Structure structC {
|
||||
* 0 char 1 c0 ""
|
||||
* 4 structB 12 c1 ""
|
||||
* }
|
||||
* Size = 16 Actual Alignment = 4
|
||||
*/
|
||||
Structure structC = new StructureDataType("structC", 0);
|
||||
structC.setPackingEnabled(true);
|
||||
structC.add(CharDataType.dataType, "c0", null);
|
||||
structC.add(structB, "c1", null);
|
||||
|
||||
ProgramBasedDataTypeManager dtm = program.getDataTypeManager();
|
||||
structC = (Structure) dtm.resolve(structC, null);
|
||||
|
||||
listing.createData(addr(0x1100), structC);
|
||||
|
||||
}
|
||||
|
||||
private Address addr(long offset) {
|
||||
return program.getAddressFactory().getDefaultAddressSpace().getAddress(offset);
|
||||
}
|
||||
|
||||
private Program buildProgram() throws Exception {
|
||||
ProgramBuilder builder = new ProgramBuilder("Test", ProgramBuilder._TOY);
|
||||
builder.createMemory("test1", "0x1000", 0x200);
|
||||
return builder.getProgram();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetComponentFromPath() throws Exception {
|
||||
|
||||
Data d = listing.getDataAt(addr(0x1100));
|
||||
Data c = d.getComponent(new int[] { 1 });
|
||||
assertNotNull(c);
|
||||
assertEquals("c1", c.getComponentPathName());
|
||||
|
||||
c = d.getComponent(new int[] { 1, 6 });
|
||||
assertNotNull(c);
|
||||
assertEquals("c1.b1", c.getComponentPathName());
|
||||
|
||||
c = d.getComponent(new int[] { 1, 6, 3 });
|
||||
assertNotNull(c);
|
||||
assertEquals("c1.b1.a1", c.getComponentPathName());
|
||||
|
||||
c = d.getComponent(new int[] { 1, 6, 4 }); // may not be visible in listing display
|
||||
assertNotNull(c);
|
||||
assertEquals("c1.b1.aflex", c.getComponentPathName());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetComponentContainingAt() throws Exception {
|
||||
|
||||
Data d = listing.getDataAt(addr(0x1100));
|
||||
Data c = d.getComponentContaining(4);
|
||||
assertNotNull(c);
|
||||
assertEquals("c1", c.getComponentPathName());
|
||||
|
||||
Data c2 = c.getComponentContaining(4);
|
||||
assertNotNull(c2);
|
||||
assertEquals("c1.", c2.getComponentPathName()); // zero-bitfield has no name
|
||||
|
||||
Data c3 = c.getComponentContaining(5);
|
||||
assertNotNull(c3);
|
||||
assertEquals("c1.bf2", c3.getComponentPathName());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetComponentsContaining() throws Exception {
|
||||
|
||||
Data d = listing.getDataAt(addr(0x1100));
|
||||
Data c = d.getComponent(new int[] { 1 });
|
||||
assertNotNull(c);
|
||||
assertEquals("c1", c.getComponentPathName());
|
||||
|
||||
List<Data> dataComponents = c.getComponentsContaining(4);
|
||||
assertEquals("[int:0 , db[0] , int:4 0h, int:6 0h]", dataComponents.toString());
|
||||
|
||||
c = d.getComponent(new int[] { 1, 6 });
|
||||
assertNotNull(c);
|
||||
assertEquals("c1.b1", c.getComponentPathName());
|
||||
|
||||
dataComponents = c.getComponentsContaining(4);
|
||||
assertEquals("[char[0] , ?? 00h]", dataComponents.toString());
|
||||
|
||||
dataComponents = c.getComponentsContaining(5);
|
||||
assertEquals("[db 0h]", dataComponents.toString());
|
||||
|
||||
// last structA.aflex component is beyond data bounds
|
||||
dataComponents = c.getComponentsContaining(6);
|
||||
assertNull(dataComponents);
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue