brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.8 KiB · 4113878 Raw
392 lines · cpp
1//===-- TestObjectFileELF.cpp ---------------------------------------------===//2//3//4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5// See https://llvm.org/LICENSE.txt for license information.6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7//8//===----------------------------------------------------------------------===//9 10#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"11#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"12#include "TestingSupport/SubsystemRAII.h"13#include "TestingSupport/TestUtilities.h"14#include "lldb/Core/Module.h"15#include "lldb/Core/ModuleSpec.h"16#include "lldb/Core/Section.h"17#include "lldb/Host/FileSystem.h"18#include "lldb/Host/HostInfo.h"19#include "lldb/Utility/DataBufferHeap.h"20#include "llvm/Support/Compression.h"21#include "llvm/Support/FileUtilities.h"22#include "llvm/Support/Path.h"23#include "llvm/Support/Program.h"24#include "llvm/Support/raw_ostream.h"25#include "llvm/Testing/Support/Error.h"26#include "gtest/gtest.h"27 28using namespace lldb_private;29using namespace lldb;30 31class ObjectFileELFTest : public testing::Test {32  SubsystemRAII<FileSystem, HostInfo, ObjectFileELF, SymbolFileSymtab>33      subsystems;34};35 36TEST_F(ObjectFileELFTest, SectionsResolveConsistently) {37  auto ExpectedFile = TestFile::fromYaml(R"(38--- !ELF39FileHeader:40  Class:           ELFCLASS6441  Data:            ELFDATA2LSB42  Type:            ET_EXEC43  Machine:         EM_X86_6444  Entry:           0x000000000040018045Sections:46  - Name:            .note.gnu.build-id47    Type:            SHT_NOTE48    Flags:           [ SHF_ALLOC ]49    Address:         0x000000000040015850    AddressAlign:    0x000000000000000451    Content:         040000001400000003000000474E55003F3EC29E3FD83E49D18C4D49CD8A730CC13117B652  - Name:            .text53    Type:            SHT_PROGBITS54    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]55    Address:         0x000000000040018056    AddressAlign:    0x000000000000001057    Content:         554889E58B042500106000890425041060005DC358  - Name:            .data59    Type:            SHT_PROGBITS60    Flags:           [ SHF_WRITE, SHF_ALLOC ]61    Address:         0x000000000060100062    AddressAlign:    0x000000000000000463    Content:         2F00000064  - Name:            .bss65    Type:            SHT_NOBITS66    Flags:           [ SHF_WRITE, SHF_ALLOC ]67    Address:         0x000000000060100468    AddressAlign:    0x000000000000000469    Size:            0x000000000000000470Symbols:71  - Name:            Y72    Type:            STT_OBJECT73    Section:         .data74    Value:           0x000000000060100075    Size:            0x000000000000000476    Binding:         STB_GLOBAL77  - Name:            _start78    Type:            STT_FUNC79    Section:         .text80    Value:           0x000000000040018081    Size:            0x000000000000001482    Binding:         STB_GLOBAL83  - Name:            X84    Type:            STT_OBJECT85    Section:         .bss86    Value:           0x000000000060100487    Size:            0x000000000000000488    Binding:         STB_GLOBAL89...90)");91  ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());92 93  auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());94  SectionList *list = module_sp->GetSectionList();95  ASSERT_NE(nullptr, list);96 97  auto bss_sp = list->FindSectionByName(ConstString(".bss"));98  ASSERT_NE(nullptr, bss_sp);99  auto data_sp = list->FindSectionByName(ConstString(".data"));100  ASSERT_NE(nullptr, data_sp);101  auto text_sp = list->FindSectionByName(ConstString(".text"));102  ASSERT_NE(nullptr, text_sp);103 104  const Symbol *X = module_sp->FindFirstSymbolWithNameAndType(ConstString("X"),105                                                              eSymbolTypeAny);106  ASSERT_NE(nullptr, X);107  EXPECT_EQ(bss_sp, X->GetAddress().GetSection());108 109  const Symbol *Y = module_sp->FindFirstSymbolWithNameAndType(ConstString("Y"),110                                                              eSymbolTypeAny);111  ASSERT_NE(nullptr, Y);112  EXPECT_EQ(data_sp, Y->GetAddress().GetSection());113 114  const Symbol *start = module_sp->FindFirstSymbolWithNameAndType(115      ConstString("_start"), eSymbolTypeAny);116  ASSERT_NE(nullptr, start);117  EXPECT_EQ(text_sp, start->GetAddress().GetSection());118}119 120// Test that GetModuleSpecifications works on an "atypical" object file which121// has section headers right after the ELF header (instead of the more common122// layout where the section headers are at the very end of the object file).123//124// Test file generated with yaml2obj (@svn rev 324254) from the following input:125/*126--- !ELF127FileHeader:128  Class:           ELFCLASS64129  Data:            ELFDATA2LSB130  Type:            ET_EXEC131  Machine:         EM_X86_64132  Entry:           0x00000000004003D0133Sections:134  - Name:            .note.gnu.build-id135    Type:            SHT_NOTE136    Flags:           [ SHF_ALLOC ]137    Address:         0x0000000000400274138    AddressAlign:    0x0000000000000004139    Content:         040000001400000003000000474E55001B8A73AC238390E32A7FF4AC8EBE4D6A41ECF5C9140  - Name:            .text141    Type:            SHT_PROGBITS142    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]143    Address:         0x00000000004003D0144    AddressAlign:    0x0000000000000010145    Content:         DEADBEEFBAADF00D146...147*/148TEST_F(ObjectFileELFTest, GetModuleSpecifications_EarlySectionHeaders) {149  std::string SO = GetInputFilePath("early-section-headers.so");150  ModuleSpecList Specs;151  ASSERT_EQ(1u, ObjectFile::GetModuleSpecifications(FileSpec(SO), 0, 0, Specs));152  ModuleSpec Spec;153  ASSERT_TRUE(Specs.GetModuleSpecAtIndex(0, Spec)) ;154  UUID Uuid;155  Uuid.SetFromStringRef("1b8a73ac238390e32a7ff4ac8ebe4d6a41ecf5c9");156  EXPECT_EQ(Spec.GetUUID(), Uuid);157}158 159TEST_F(ObjectFileELFTest, GetModuleSpecifications_OffsetSizeWithNormalFile) {160  std::string SO = GetInputFilePath("liboffset-test.so");161  ModuleSpecList Specs;162  ASSERT_EQ(1u, ObjectFile::GetModuleSpecifications(FileSpec(SO), 0, 0, Specs));163  ModuleSpec Spec;164  ASSERT_TRUE(Specs.GetModuleSpecAtIndex(0, Spec)) ;165  UUID Uuid;166  Uuid.SetFromStringRef("7D6E4738");167  EXPECT_EQ(Spec.GetUUID(), Uuid);168  EXPECT_EQ(Spec.GetObjectOffset(), 0UL);169  EXPECT_EQ(Spec.GetObjectSize(), 3600UL);170  EXPECT_EQ(FileSystem::Instance().GetByteSize(FileSpec(SO)), 3600UL);171}172 173TEST_F(ObjectFileELFTest, GetModuleSpecifications_OffsetSizeWithOffsetFile) {174  // The contents of offset-test.bin are175  // -    0-1023: \0176  // - 1024-4623: liboffset-test.so (offset: 1024, size: 3600, CRC32: 7D6E4738)177  // - 4624-4639: \0178  std::string SO = GetInputFilePath("offset-test.bin");179  ModuleSpecList Specs;180  ASSERT_EQ(181      1u, ObjectFile::GetModuleSpecifications(FileSpec(SO), 1024, 3600, Specs));182  ModuleSpec Spec;183  ASSERT_TRUE(Specs.GetModuleSpecAtIndex(0, Spec)) ;184  UUID Uuid;185  Uuid.SetFromStringRef("7D6E4738");186  EXPECT_EQ(Spec.GetUUID(), Uuid);187  EXPECT_EQ(Spec.GetObjectOffset(), 1024UL);188  EXPECT_EQ(Spec.GetObjectSize(), 3600UL);189  EXPECT_EQ(FileSystem::Instance().GetByteSize(FileSpec(SO)), 4640UL);190}191 192TEST_F(ObjectFileELFTest, GetSymtab_NoSymEntryPointArmThumbAddressClass) {193  /*194  // nosym-entrypoint-arm-thumb.s195  .thumb_func196  _start:197      mov r0, #42198      mov r7, #1199      svc #0200  // arm-linux-androideabi-as nosym-entrypoint-arm-thumb.s201  //   -o nosym-entrypoint-arm-thumb.o202  // arm-linux-androideabi-ld nosym-entrypoint-arm-thumb.o203  //   -o nosym-entrypoint-arm-thumb -e 0x8075 -s204  */205  auto ExpectedFile = TestFile::fromYaml(R"(206--- !ELF207FileHeader:208  Class:           ELFCLASS32209  Data:            ELFDATA2LSB210  Type:            ET_EXEC211  Machine:         EM_ARM212  Flags:           [ EF_ARM_SOFT_FLOAT, EF_ARM_EABI_VER5 ]213  Entry:           0x0000000000008075214Sections:215  - Name:            .text216    Type:            SHT_PROGBITS217    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]218    Address:         0x0000000000008074219    AddressAlign:    0x0000000000000002220    Content:         2A20012700DF221  - Name:            .data222    Type:            SHT_PROGBITS223    Flags:           [ SHF_WRITE, SHF_ALLOC ]224    Address:         0x0000000000009000225    AddressAlign:    0x0000000000000001226    Content:         ''227  - Name:            .bss228    Type:            SHT_NOBITS229    Flags:           [ SHF_WRITE, SHF_ALLOC ]230    Address:         0x0000000000009000231    AddressAlign:    0x0000000000000001232  - Name:            .note.gnu.gold-version233    Type:            SHT_NOTE234    AddressAlign:    0x0000000000000004235    Content:         040000000900000004000000474E5500676F6C6420312E3131000000236  - Name:            .ARM.attributes237    Type:            SHT_ARM_ATTRIBUTES238    AddressAlign:    0x0000000000000001239    Content:         '4113000000616561626900010900000006020901'240...241)");242  ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());243 244  auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());245 246  auto entry_point_addr = module_sp->GetObjectFile()->GetEntryPointAddress();247  ASSERT_TRUE(entry_point_addr.GetOffset() & 1);248  // Decrease the offsite by 1 to make it into a breakable address since this249  // is Thumb.250  entry_point_addr.SetOffset(entry_point_addr.GetOffset() - 1);251  ASSERT_EQ(entry_point_addr.GetAddressClass(),252            AddressClass::eCodeAlternateISA);253}254 255TEST_F(ObjectFileELFTest, GetSymtab_NoSymEntryPointArmAddressClass) {256  /*257  // nosym-entrypoint-arm.s258  _start:259      movs r0, #42260      movs r7, #1261      svc #0262  // arm-linux-androideabi-as nosym-entrypoint-arm.s263  //   -o nosym-entrypoint-arm.o264  // arm-linux-androideabi-ld nosym-entrypoint-arm.o265  //   -o nosym-entrypoint-arm -e 0x8074 -s266  */267  auto ExpectedFile = TestFile::fromYaml(R"(268--- !ELF269FileHeader:270  Class:           ELFCLASS32271  Data:            ELFDATA2LSB272  Type:            ET_EXEC273  Machine:         EM_ARM274  Flags:           [ EF_ARM_SOFT_FLOAT, EF_ARM_EABI_VER5 ]275  Entry:           0x0000000000008074276Sections:277  - Name:            .text278    Type:            SHT_PROGBITS279    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]280    Address:         0x0000000000008074281    AddressAlign:    0x0000000000000004282    Content:         2A00A0E30170A0E3000000EF283  - Name:            .data284    Type:            SHT_PROGBITS285    Flags:           [ SHF_WRITE, SHF_ALLOC ]286    Address:         0x0000000000009000287    AddressAlign:    0x0000000000000001288    Content:         ''289  - Name:            .bss290    Type:            SHT_NOBITS291    Flags:           [ SHF_WRITE, SHF_ALLOC ]292    Address:         0x0000000000009000293    AddressAlign:    0x0000000000000001294  - Name:            .note.gnu.gold-version295    Type:            SHT_NOTE296    AddressAlign:    0x0000000000000004297    Content:         040000000900000004000000474E5500676F6C6420312E3131000000298  - Name:            .ARM.attributes299    Type:            SHT_ARM_ATTRIBUTES300    AddressAlign:    0x0000000000000001301    Content:         '4113000000616561626900010900000006010801'302...303)");304  ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());305 306  auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());307 308  auto entry_point_addr = module_sp->GetObjectFile()->GetEntryPointAddress();309  ASSERT_EQ(entry_point_addr.GetAddressClass(), AddressClass::eCode);310}311 312TEST_F(ObjectFileELFTest, SkipsLocalMappingAndDotLSymbols) {313  auto ExpectedFile = TestFile::fromYaml(R"(314--- !ELF315  FileHeader:316    Class:           ELFCLASS64317    Data:            ELFDATA2LSB318    Type:            ET_EXEC319    Machine:         EM_RISCV320    Flags:           [ EF_RISCV_RVC, EF_RISCV_FLOAT_ABI_SINGLE ]321    Entry:           0xC0A1B010322  Sections:323    - Name:            .text324      Type:            SHT_PROGBITS325      Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]326      Address:         0x0000000000400180327      AddressAlign:    0x0000000000000010328      Content:         554889E5329    - Name:            .data330      Type:            SHT_PROGBITS331      Flags:           [ SHF_WRITE, SHF_ALLOC ]332      Address:         0x0000000000601000333      AddressAlign:    0x0000000000000004334      Content:         2F000000335    - Name:            .riscv.attributes336      Type:            SHT_PROGBITS337      Flags:           [ SHF_ALLOC ]338      Address:         0x0000000000610000339      AddressAlign:    0x0000000000000004340      Content:         "00"341  Symbols:342    - Name:            $d343      Type:            STT_NOTYPE344      Section:         .riscv.attributes345      Value:           0x0000000000400180346      Size:            0x10347      Binding:         STB_LOCAL348    - Name:            $x349      Type:            STT_NOTYPE350      Section:         .text351      Value:           0xC0A1B010352      Size:            0x10353      Binding:         STB_LOCAL354    - Name:            .Lfoo355      Type:            STT_OBJECT356      Section:         .data357      Value:           0x0000000000601000358      Size:            0x4359      Binding:         STB_LOCAL360    - Name:            global_func361      Type:            STT_FUNC362      Section:         .text363      Value:           0x00000000004001A0364      Size:            0x10365      Binding:         STB_GLOBAL366    - Name:            global_obj367      Type:            STT_OBJECT368      Section:         .data369      Value:           0x0000000000601004370      Size:            0x4371      Binding:         STB_GLOBAL372...373  )");374  ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());375  auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());376  auto *symtab = module_sp->GetSymtab();377  ASSERT_NE(nullptr, symtab);378  EXPECT_EQ(nullptr, module_sp->FindFirstSymbolWithNameAndType(379                         ConstString("$d"), eSymbolTypeAny));380  EXPECT_EQ(nullptr, module_sp->FindFirstSymbolWithNameAndType(381                         ConstString("$x"), eSymbolTypeAny));382  EXPECT_EQ(nullptr, module_sp->FindFirstSymbolWithNameAndType(383                         ConstString(".Lfoo"), eSymbolTypeAny));384  // assert that other symbols are present385  const Symbol *global_func = module_sp->FindFirstSymbolWithNameAndType(386      ConstString("global_func"), eSymbolTypeAny);387  ASSERT_NE(nullptr, global_func);388  const Symbol *global_obj = module_sp->FindFirstSymbolWithNameAndType(389      ConstString("global_obj"), eSymbolTypeAny);390  ASSERT_NE(nullptr, global_obj);391}392