Skip to content

Commit df6d2fa

Browse files
authored
[Object] Provide operator< for ELFSymbolRef (#89861)
Normally, operator< accepting DataRefImpl is used when comparing SymbolRef/ELFSymbolRef. However, it uses std::memcmp which interprets DataRefImpl union as char string so that the result depends on host endianness. For ELFSymbolRef a specialized operator< can be used instead to produce consistent ordering regardless of endianness by comparing the symbol table index and symbol index fields separately.
1 parent 1e174a7 commit df6d2fa

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

llvm/include/llvm/Object/ELFObjectFile.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,14 @@ class ELFSymbolRef : public SymbolRef {
199199
}
200200
};
201201

202+
inline bool operator<(const ELFSymbolRef &A, const ELFSymbolRef &B) {
203+
const DataRefImpl &DRIA = A.getRawDataRefImpl();
204+
const DataRefImpl &DRIB = B.getRawDataRefImpl();
205+
if (DRIA.d.a == DRIB.d.a)
206+
return DRIA.d.b < DRIB.d.b;
207+
return DRIA.d.a < DRIB.d.a;
208+
}
209+
202210
class elf_symbol_iterator : public symbol_iterator {
203211
public:
204212
elf_symbol_iterator(const basic_symbol_iterator &B)

llvm/unittests/Object/ELFObjectFileTest.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1504,3 +1504,46 @@ TEST(ELFObjectFileTest, GetSectionAndRelocations) {
15041504
"SHT_RELA section with index 1: failed to get a "
15051505
"relocated section: invalid section index: 255");
15061506
}
1507+
1508+
TEST(ELFObjectFileTest, ELFSymbolRefLess) {
1509+
SmallString<0> Storage;
1510+
Expected<ELFObjectFile<ELF64LE>> ElfOrErr = toBinary<ELF64LE>(Storage, R"(
1511+
--- !ELF
1512+
FileHeader:
1513+
Class: ELFCLASS64
1514+
Data: ELFDATA2LSB
1515+
Type: ET_DYN
1516+
Machine: EM_X86_64
1517+
)");
1518+
1519+
ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());
1520+
const ELFObjectFile<ELF64LE> &Obj = *ElfOrErr;
1521+
1522+
const uint32_t ValLow = 0x00000001;
1523+
const uint32_t ValHigh = 0x00000100;
1524+
1525+
auto MakeSymbol = [&Obj](size_t SymtabIndex, size_t SymbolIndex) {
1526+
DataRefImpl Data;
1527+
Data.d.a = SymtabIndex;
1528+
Data.d.b = SymbolIndex;
1529+
SymbolRef Sym(Data, &Obj);
1530+
return ELFSymbolRef(Sym);
1531+
};
1532+
1533+
ELFSymbolRef ELFSymLowLow = MakeSymbol(ValLow, ValLow);
1534+
ELFSymbolRef ELFSymLowHigh = MakeSymbol(ValLow, ValHigh);
1535+
ELFSymbolRef ELFSymHighLow = MakeSymbol(ValHigh, ValLow);
1536+
ELFSymbolRef ELFSymHighHigh = MakeSymbol(ValHigh, ValHigh);
1537+
1538+
EXPECT_TRUE(ELFSymLowLow < ELFSymLowHigh);
1539+
EXPECT_FALSE(ELFSymLowHigh < ELFSymLowLow);
1540+
EXPECT_FALSE(ELFSymLowLow < ELFSymLowLow);
1541+
1542+
EXPECT_TRUE(ELFSymLowLow < ELFSymHighHigh);
1543+
EXPECT_TRUE(ELFSymLowHigh < ELFSymHighLow);
1544+
EXPECT_TRUE(ELFSymLowLow < ELFSymHighLow);
1545+
1546+
EXPECT_FALSE(ELFSymHighLow < ELFSymLowHigh);
1547+
EXPECT_FALSE(ELFSymHighHigh < ELFSymLowLow);
1548+
EXPECT_FALSE(ELFSymHighLow < ELFSymLowLow);
1549+
}

0 commit comments

Comments
 (0)