@@ -355,8 +355,8 @@ class BaseRelocChunk : public SectionChunk {
355
355
typedef std::vector<std::unique_ptr<Chunk> > ChunkVectorT;
356
356
357
357
public:
358
- typedef std::pair<uint16_t , llvm::COFF::BaseRelocationType> BaseRelocation;
359
- typedef std::vector<BaseRelocation> BaseRelocations;
358
+ typedef std::vector<std:: pair<uint16_t , llvm::COFF::BaseRelocationType>>
359
+ BaseRelocations;
360
360
typedef std::map<uint64_t , BaseRelocations> RelocationBlocks;
361
361
362
362
BaseRelocChunk (ChunkVectorT &chunks, const PECOFFLinkingContext &ctx)
@@ -382,13 +382,11 @@ class BaseRelocChunk : public SectionChunk {
382
382
// at an address different from its preferred one.
383
383
AtomChunk::BaseRelocationList listRelocSites (ChunkVectorT &chunks) const ;
384
384
385
- // Divide the given RVAs into blocks.
386
- RelocationBlocks
387
- groupByPage (const AtomChunk::BaseRelocationList &relocSites) const ;
388
-
389
385
// Create the content of a relocation block.
390
386
std::vector<uint8_t >
391
- createBaseRelocBlock (uint64_t pageAddr, const BaseRelocations &relocs) const ;
387
+ createBaseRelocBlock (uint64_t pageAddr,
388
+ const AtomChunk::BaseRelocation *begin,
389
+ const AtomChunk::BaseRelocation *end) const ;
392
390
393
391
const PECOFFLinkingContext &_ctx;
394
392
std::vector<uint8_t > _contents;
@@ -965,11 +963,24 @@ std::vector<uint8_t>
965
963
BaseRelocChunk::createContents (ChunkVectorT &chunks) const {
966
964
std::vector<uint8_t > contents;
967
965
AtomChunk::BaseRelocationList relocSites = listRelocSites (chunks);
968
- RelocationBlocks blocks = groupByPage (relocSites);
969
- for (auto &i : blocks) {
970
- uint64_t pageAddr = i.first ;
971
- const BaseRelocations &relocs = i.second ;
972
- std::vector<uint8_t > block = createBaseRelocBlock (pageAddr, relocs);
966
+
967
+ uint64_t mask = _ctx.getPageSize () - 1 ;
968
+ parallel_sort (relocSites.begin (), relocSites.end (),
969
+ [&](const AtomChunk::BaseRelocation &a,
970
+ const AtomChunk::BaseRelocation &b) {
971
+ return (a.first & ~mask) < (b.first & ~mask);
972
+ });
973
+
974
+ // Base relocations for the same memory page are grouped together
975
+ // and passed to createBaseRelocBlock.
976
+ for (size_t i = 0 , e = relocSites.size (); i < e; ++i) {
977
+ const AtomChunk::BaseRelocation *begin = &relocSites[i];
978
+ uint64_t pageAddr = (begin->first & ~mask);
979
+ for (++i; i < e; ++i)
980
+ if ((relocSites[i].first & ~mask) != pageAddr)
981
+ break ;
982
+ const AtomChunk::BaseRelocation *end = &relocSites[i];
983
+ std::vector<uint8_t > block = createBaseRelocBlock (pageAddr, begin, end);
973
984
contents.insert (contents.end (), block.begin (), block.end ());
974
985
}
975
986
return contents;
@@ -986,25 +997,16 @@ BaseRelocChunk::listRelocSites(ChunkVectorT &chunks) const {
986
997
return ret;
987
998
}
988
999
989
- // Divide the given RVAs into blocks.
990
- BaseRelocChunk::RelocationBlocks BaseRelocChunk::groupByPage (
991
- const AtomChunk::BaseRelocationList &relocSites) const {
992
- RelocationBlocks blocks;
993
- uint64_t mask = _ctx.getPageSize () - 1 ;
994
- for (const auto &reloc : relocSites)
995
- blocks[reloc.first & ~mask].push_back (
996
- std::make_pair (reloc.first & mask, reloc.second ));
997
- return blocks;
998
- }
999
-
1000
1000
// Create the content of a relocation block.
1001
1001
std::vector<uint8_t >
1002
- BaseRelocChunk::createBaseRelocBlock (uint64_t pageAddr,
1003
- const BaseRelocations &relocs) const {
1002
+ BaseRelocChunk::createBaseRelocBlock (
1003
+ uint64_t pageAddr,
1004
+ const AtomChunk::BaseRelocation *begin,
1005
+ const AtomChunk::BaseRelocation *end) const {
1004
1006
// Relocation blocks should be padded with IMAGE_REL_I386_ABSOLUTE to be
1005
1007
// aligned to a DWORD size boundary.
1006
1008
uint32_t size = llvm::RoundUpToAlignment (
1007
- sizeof (ulittle32_t ) * 2 + sizeof (ulittle16_t ) * relocs. size ( ),
1009
+ sizeof (ulittle32_t ) * 2 + sizeof (ulittle16_t ) * (end - begin ),
1008
1010
sizeof (ulittle32_t ));
1009
1011
std::vector<uint8_t > contents (size);
1010
1012
uint8_t *ptr = &contents[0 ];
@@ -1018,9 +1020,9 @@ BaseRelocChunk::createBaseRelocBlock(uint64_t pageAddr,
1018
1020
write32le (ptr, size);
1019
1021
ptr += sizeof (ulittle32_t );
1020
1022
1021
- for ( const auto &reloc : relocs) {
1022
- assert (reloc. first < _ctx. getPageSize ());
1023
- write16le (ptr, (reloc. second << 12 ) | reloc. first );
1023
+ uint64_t mask = _ctx. getPageSize () - 1 ;
1024
+ for ( const AtomChunk::BaseRelocation *i = begin; i < end; ++i) {
1025
+ write16le (ptr, (i-> second << 12 ) | (i-> first & mask) );
1024
1026
ptr += sizeof (ulittle16_t );
1025
1027
}
1026
1028
return contents;
0 commit comments