diff --git a/CHANGELOG.md b/CHANGELOG.md index c6d5bc1c..30f06874 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ Heuristic weights can now be modified by providing user hints. * Generate GOT, PAGE and GOT, OFST symbolic expression attributes for split .got loads on MIPS. +* Correct symbol_minus_symbol in lsda entries with a reference to the end of `.gcc_except_table`: add `boundary_sym_expr` for such reference # 1.8.0 diff --git a/examples/ex_exceptions4/Makefile b/examples/ex_exceptions4/Makefile new file mode 100644 index 00000000..7b586664 --- /dev/null +++ b/examples/ex_exceptions4/Makefile @@ -0,0 +1,20 @@ +CXX="g++" +EXEC= + +all: ex.cpp + # NOTE: `-T linker-script.ld` + # This is to place .gcc_except_table *before* .note.gnu.build-id + # so that the reference label for the end of the section is aligned + # with the adjacent section. + # + # With this example, if a boundary_sym_expr is not correctly created + # for symbol_minus_symbol, the assembler will fail with + # "Error: invalid operands for '-'" + $(CXX) ex.cpp $(CXXFLAGS) -T linker-script.ld -o ex + @ $(EXEC) ./ex > out.txt +clean: + rm -f ex out.txt + rm -fr ex.unstripped *.s *.old* dl_files *.gtirb +check: + @ $(EXEC) ./ex >/tmp/res.txt + @ diff out.txt /tmp/res.txt && echo TEST OK diff --git a/examples/ex_exceptions4/ex.cpp b/examples/ex_exceptions4/ex.cpp new file mode 100644 index 00000000..3d106b0f --- /dev/null +++ b/examples/ex_exceptions4/ex.cpp @@ -0,0 +1,16 @@ +#include +#include + +int main() +{ + try + { + throw std::logic_error("This is a logic error"); + } + catch(std::exception& e) + { + std::cout << e.what() << std::endl; + } + + return 0; +} diff --git a/examples/ex_exceptions4/linker-script.ld b/examples/ex_exceptions4/linker-script.ld new file mode 100644 index 00000000..26110fdd --- /dev/null +++ b/examples/ex_exceptions4/linker-script.ld @@ -0,0 +1,4 @@ +SECTIONS { + .gcc_except_table : { *(.gcc_except_table) } +} +INSERT BEFORE .note.gnu.build-id; diff --git a/src/datalog/binary/elf/exceptions.dl b/src/datalog/binary/elf/exceptions.dl index 8aaf7668..f1246046 100644 --- a/src/datalog/binary/elf/exceptions.dl +++ b/src/datalog/binary/elf/exceptions.dl @@ -172,9 +172,24 @@ labeled_ea(Personality):- ///////////////////////////////////////////////////////////////////////////////// // Symbols in lsda +/** +Same as `symbol_minus_symbol`: this is to avoid cyclic aggregation by +`boundary_sym_expr` using `symbol_minus_symbol`. +*/ +.decl lsda_symbol_minus_symbol(EA:address,Size:unsigned,Symbol1:address,Symbol2:address,Scale:unsigned,Offset:number) + +symbol_minus_symbol(EA,Size,Symbol1,Symbol2,Scale,Offset):- + lsda_symbol_minus_symbol(EA,Size,Symbol1,Symbol2,Scale,Offset). + +// If the second address is the end of the section, create `boundary_sym_expr` +// for the address. +boundary_sym_expr(EA, Dest):- + lsda_symbol_minus_symbol(EA,_,_,Dest,_,_), + loaded_section(_,Dest,_). + // type table pointer symbol_special_encoding(TypeTablePointerLocation,"uleb128"), -symbol_minus_symbol(TypeTablePointerLocation,Size,CallsiteTablePointerLoc-1,LsdaTypeTableAddress,1,0):- +lsda_symbol_minus_symbol(TypeTablePointerLocation,Size,CallsiteTablePointerLoc-1,LsdaTypeTableAddress,1,0):- lsda_pointer_locations(Lsda,TypeTablePointerLocation,CallsiteTablePointerLoc), lsda(Lsda,_,_,_,LsdaTypeTableAddress, _, _), LsdaTypeTableAddress != 0, @@ -183,7 +198,7 @@ symbol_minus_symbol(TypeTablePointerLocation,Size,CallsiteTablePointerLoc-1,Lsda //callsite table size symbol_special_encoding(CallsiteTablePointerLoc,"uleb128"), -symbol_minus_symbol(CallsiteTablePointerLoc,Size,CallSiteTable_address,CallSiteTable_address+CallSiteTableLength,1,0):- +lsda_symbol_minus_symbol(CallsiteTablePointerLoc,Size,CallSiteTable_address,CallSiteTable_address+CallSiteTableLength,1,0):- lsda_pointer_locations(Lsda,_,CallsiteTablePointerLoc), lsda(Lsda,CallSiteTable_address,_,CallSiteTableLength,_, _, _), Size = CallSiteTable_address - CallsiteTablePointerLoc, @@ -202,7 +217,7 @@ symbol_special_encoding(EA_landingPad,EncodingName):- //region beginning -symbol_minus_symbol(EA_start,Size,LandingPadBaseAddress,StartRegion,1,0):- +lsda_symbol_minus_symbol(EA_start,Size,LandingPadBaseAddress,StartRegion,1,0):- lsda_callsite(CallSiteTable_address, EA_start, StartRegion,EA_end,_,_,_,_), lsda(_,CallSiteTable_address,_,_,_,_,LandingPadBaseAddress), Size = EA_end-EA_start, @@ -210,7 +225,7 @@ symbol_minus_symbol(EA_start,Size,LandingPadBaseAddress,StartRegion,1,0):- //region end boundary_sym_expr(EA_end,EndRegion), -symbol_minus_symbol(EA_end,Size,StartRegion,EndRegion,1,0):- +lsda_symbol_minus_symbol(EA_end,Size,StartRegion,EndRegion,1,0):- lsda_callsite(_, _, StartRegion,EA_end,EndRegion,EA_landingPad,_,_), Size = EA_landingPad-EA_end, Size > 0, @@ -218,7 +233,7 @@ symbol_minus_symbol(EA_end,Size,StartRegion,EndRegion,1,0):- block_boundaries(_,_,EndRegion). //landing pad -symbol_minus_symbol(EA_landingPad,Size,LandingPadBaseAddress,LandingPad,1,0):- +lsda_symbol_minus_symbol(EA_landingPad,Size,LandingPadBaseAddress,LandingPad,1,0):- lsda_callsite(CallSiteTable_address, _, _,_,_,EA_landingPad,LandingPad,EA_endLandingPad), lsda(_,CallSiteTable_address,_,_,_,_,LandingPadBaseAddress), LandingPad != 0, @@ -236,7 +251,7 @@ symbolic_data(EAType,EncodingSize,Type):- EAType=LsdaTypeTableAddress-(EncodingSize*(Index+1)), Type != 0. -symbol_minus_symbol(EAType,EncodingSize,EAType,Type,1,0):- +lsda_symbol_minus_symbol(EAType,EncodingSize,EAType,Type,1,0):- lsda_type_entry(LsdaTypeTableAddress, Index,Type), lsda(_,_,_,_,LsdaTypeTableAddress, TypeTableEncoding, _), TypeTableEncoding band 0xF = Encoding, diff --git a/tests/linux-elf-x64.yaml b/tests/linux-elf-x64.yaml index 5b3dacd3..457379e8 100644 --- a/tests/linux-elf-x64.yaml +++ b/tests/linux-elf-x64.yaml @@ -168,6 +168,9 @@ tests: - name: ex_exceptions3 <<: *default-cpp + - name: ex_exceptions4 + <<: *default-cpp + - name: ex_false_pointer_array <<: *default @@ -375,6 +378,10 @@ tests: <<: *default-cpp <<: *test-strip-default + - name: ex_exceptions4 + <<: *default-cpp + <<: *test-strip-default + - name: ex_false_pointer_array <<: *default <<: *test-strip-default @@ -664,6 +671,10 @@ tests: # - name: ex_exceptions3 # <<: *cpp-object + # TODO: + # - name: ex_exceptions4 + # <<: *cpp-object + - name: ex_false_pointer_array <<: *c-object diff --git a/tests/linux-elf-x86.yaml b/tests/linux-elf-x86.yaml index 1f89912e..633859d7 100644 --- a/tests/linux-elf-x86.yaml +++ b/tests/linux-elf-x86.yaml @@ -126,6 +126,9 @@ tests: - name: ex_exceptions3 <<: *default-cpp + - name: ex_exceptions4 + <<: *default-cpp + - name: ex_false_pointer_array <<: *default @@ -212,6 +215,9 @@ tests: - name: ex_exceptions3 <<: *position-independent-cpp + - name: ex_exceptions4 + <<: *position-independent-cpp + - name: ex_false_pointer_array <<: *position-independent test: