mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-08-08 07:40:39 -09:00
Merge branch 'GP-0_ryanmkurtz_PR-9427_mi11ione_fix-lsda-ttype-base'
This commit is contained in:
@@ -150,8 +150,8 @@ public class LSDAHeader extends GccAnalysisClass {
|
||||
|
||||
LEB128Info uleb128 = GccAnalysisUtils.readULEB128Info(program, addr);
|
||||
|
||||
// this offset it based from *here*..
|
||||
ttypeOffset = uleb128.asLong() + curSize;
|
||||
// this offset is based from the end of *this* field, and the base is the table's last byte
|
||||
ttypeOffset = uleb128.asLong() + curSize + uleb128.getLength() - 1;
|
||||
|
||||
createAndCommentData(program, addr, UnsignedLeb128DataType.dataType, comment,
|
||||
CommentType.EOL);
|
||||
@@ -306,7 +306,7 @@ public class LSDAHeader extends GccAnalysisClass {
|
||||
}
|
||||
|
||||
/**
|
||||
* The offset from the type offset field to get to the base address of the type table.
|
||||
* The offset from the start of the LSDA to the base address of the type table.
|
||||
* @return the type table offset
|
||||
*/
|
||||
public int getTTypeOffset() {
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.util.List;
|
||||
|
||||
import ghidra.app.cmd.comments.SetCommentCmd;
|
||||
import ghidra.app.plugin.exceptionhandlers.gcc.*;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.listing.CommentType;
|
||||
import ghidra.program.model.listing.Program;
|
||||
@@ -100,7 +100,8 @@ public class LSDATypeTable extends GccAnalysisClass {
|
||||
}
|
||||
|
||||
}
|
||||
catch (MemoryAccessException mae) {
|
||||
catch (MemoryAccessException | AddressOutOfBoundsException e) {
|
||||
// a pc-relative entry landing outside the address space throws the unchecked one
|
||||
SetCommentCmd commentCmd =
|
||||
new SetCommentCmd(addr, CommentType.EOL, "Unable to resolve pointer");
|
||||
commentCmd.applyTo(program);
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
/* ###
|
||||
* 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.app.plugin.exceptionhandlers.gcc.structures.gccexcepttable;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.app.plugin.exceptionhandlers.gcc.RegionDescriptor;
|
||||
import ghidra.program.database.ProgramBuilder;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* Tests that the LSDA header locates the type table correctly however many bytes the TType
|
||||
* offset ULEB128 occupies. Each LSDA below runs LPStart encoding (omitted), TType encoding
|
||||
* (pcrel|sdata4), TType offset, call site encoding (uleb128) and table length, call site
|
||||
* records, action table, then a single type table entry ending at the type table base.
|
||||
*/
|
||||
public class LSDAHeaderTest extends AbstractGenericTest {
|
||||
|
||||
private ProgramBuilder builder;
|
||||
private Program program;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
builder = new ProgramBuilder("lsda", ProgramBuilder._X64);
|
||||
builder.createMemory("lsda", "0x1000", 0x400);
|
||||
program = builder.getProgram();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
builder.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleByteTTypeOffset() throws Exception {
|
||||
builder.setBytes("0x1000", "ff 1b 0d 01 04 00 02 02 01 01 00 00 f4 02 00 00");
|
||||
|
||||
LSDATable table = createTable();
|
||||
|
||||
assertEquals(addr(0x100f), table.getHeader().getTTypeBaseAddress());
|
||||
assertEquals(addr(0x1300), table.getTypeTable().getTypeInfoAddress(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwoByteTTypeOffset() throws Exception {
|
||||
builder.setBytes("0x1000",
|
||||
"ff 1b 80 01 01 78 " + "00 02 02 01 ".repeat(30) + "01 00 80 02 00 00");
|
||||
|
||||
LSDATable table = createTable();
|
||||
|
||||
assertEquals(addr(0x1083), table.getHeader().getTTypeBaseAddress());
|
||||
assertEquals(addr(0x1300), table.getTypeTable().getTypeInfoAddress(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThreeByteTTypeOffset() throws Exception {
|
||||
builder.setBytes("0x1000", "ff 1b 80 80 01 01 00");
|
||||
|
||||
LSDAHeader header = new LSDAHeader(TaskMonitor.DUMMY, program, region());
|
||||
int id = program.startTransaction("lsda");
|
||||
try {
|
||||
header.create(addr(0x1000));
|
||||
}
|
||||
finally {
|
||||
program.endTransaction(id, true);
|
||||
}
|
||||
|
||||
assertEquals(addr(0x5004), header.getTTypeBaseAddress());
|
||||
}
|
||||
|
||||
private LSDATable createTable() throws Exception {
|
||||
RegionDescriptor region = region();
|
||||
region.setLSDAAddress(addr(0x1000));
|
||||
|
||||
int id = program.startTransaction("lsda");
|
||||
try {
|
||||
LSDATable table = new LSDATable(TaskMonitor.DUMMY, program);
|
||||
table.create(addr(0x1000), region);
|
||||
return table;
|
||||
}
|
||||
finally {
|
||||
program.endTransaction(id, true);
|
||||
}
|
||||
}
|
||||
|
||||
private RegionDescriptor region() {
|
||||
RegionDescriptor region = new RegionDescriptor(program.getMemory().getBlock(addr(0x1000)));
|
||||
region.setIPRange(new AddressRangeImpl(addr(0x1000), addr(0x1100)));
|
||||
return region;
|
||||
}
|
||||
|
||||
private Address addr(long offset) {
|
||||
return program.getAddressFactory().getDefaultAddressSpace().getAddress(offset);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/* ###
|
||||
* 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.app.plugin.exceptionhandlers.gcc.structures.gccexcepttable;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.app.plugin.exceptionhandlers.gcc.RegionDescriptor;
|
||||
import ghidra.program.database.ProgramBuilder;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* Tests that an entry the type table cannot resolve costs only that entry. The type table is
|
||||
* built last, so an exception escaping it would discard the call site and action tables that
|
||||
* {@link LSDATable#create} has already finished.
|
||||
*/
|
||||
public class LSDATypeTableTest extends AbstractGenericTest {
|
||||
|
||||
private ProgramBuilder builder;
|
||||
private Program program;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
builder = new ProgramBuilder("lsda", ProgramBuilder._X64);
|
||||
builder.createMemory("lsda", "0x1000", 0x400);
|
||||
program = builder.getProgram();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
builder.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnresolvableTypeEntryKeepsCallSiteTable() throws Exception {
|
||||
// the sole type table entry is a pc-relative displacement that leaves the address space
|
||||
builder.setBytes("0x1000", "ff 1b 0d 01 04 00 02 02 01 01 00 00 01 00 00 80");
|
||||
|
||||
Address lsda = addr(0x1000);
|
||||
RegionDescriptor region = new RegionDescriptor(program.getMemory().getBlock(lsda));
|
||||
region.setIPRange(new AddressRangeImpl(lsda, addr(0x1100)));
|
||||
region.setLSDAAddress(lsda);
|
||||
|
||||
LSDATable table = new LSDATable(TaskMonitor.DUMMY, program);
|
||||
int id = program.startTransaction("lsda");
|
||||
try {
|
||||
table.create(lsda, region);
|
||||
}
|
||||
finally {
|
||||
program.endTransaction(id, true);
|
||||
}
|
||||
|
||||
assertEquals(1, table.getCallSiteTable().getCallSiteRecords().size());
|
||||
}
|
||||
|
||||
private Address addr(long offset) {
|
||||
return program.getAddressFactory().getDefaultAddressSpace().getAddress(offset);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user