|
8 | 8 |
|
9 | 9 | #include "InputFiles.h" |
10 | 10 | #include "OutputSections.h" |
| 11 | +#include "RelocScan.h" |
11 | 12 | #include "Symbols.h" |
12 | 13 | #include "SyntheticSections.h" |
13 | 14 | #include "Target.h" |
@@ -38,6 +39,10 @@ class RISCV final : public TargetInfo { |
38 | 39 | void writePltHeader(uint8_t *buf) const override; |
39 | 40 | void writePlt(uint8_t *buf, const Symbol &sym, |
40 | 41 | uint64_t pltEntryAddr) const override; |
| 42 | + template <class ELFT, class RelTy> |
| 43 | + void scanSectionImpl(InputSectionBase &, Relocs<RelTy>); |
| 44 | + template <class ELFT> void scanSection1(InputSectionBase &); |
| 45 | + void scanSection(InputSectionBase &) override; |
41 | 46 | RelType getDynRel(RelType type) const override; |
42 | 47 | RelExpr getRelExpr(RelType type, const Symbol &s, |
43 | 48 | const uint8_t *loc) const override; |
@@ -278,6 +283,7 @@ RelExpr RISCV::getRelExpr(const RelType type, const Symbol &s, |
278 | 283 | const uint8_t *loc) const { |
279 | 284 | switch (type) { |
280 | 285 | case R_RISCV_NONE: |
| 286 | + case R_RISCV_VENDOR: |
281 | 287 | return R_NONE; |
282 | 288 | case R_RISCV_32: |
283 | 289 | case R_RISCV_64: |
@@ -1476,3 +1482,54 @@ void elf::mergeRISCVAttributesSections(Ctx &ctx) { |
1476 | 1482 | } |
1477 | 1483 |
|
1478 | 1484 | void elf::setRISCVTargetInfo(Ctx &ctx) { ctx.target.reset(new RISCV(ctx)); } |
| 1485 | + |
| 1486 | +template <class ELFT, class RelTy> |
| 1487 | +void RISCV::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels) { |
| 1488 | + RelocScan rs(ctx, &sec); |
| 1489 | + // Many relocations end up in sec.relocations. |
| 1490 | + sec.relocations.reserve(rels.size()); |
| 1491 | + |
| 1492 | + StringRef rvVendor; |
| 1493 | + for (auto it = rels.begin(); it != rels.end(); ++it) { |
| 1494 | + RelType type = it->getType(false); |
| 1495 | + uint32_t symIndex = it->getSymbol(false); |
| 1496 | + Symbol &sym = sec.getFile<ELFT>()->getSymbol(symIndex); |
| 1497 | + const uint8_t *loc = sec.content().data() + it->r_offset; |
| 1498 | + |
| 1499 | + if (type == R_RISCV_VENDOR) { |
| 1500 | + if (!rvVendor.empty()) |
| 1501 | + Err(ctx) << getErrorLoc(ctx, loc) |
| 1502 | + << "malformed consecutive R_RISCV_VENDOR relocations"; |
| 1503 | + rvVendor = sym.getName(); |
| 1504 | + continue; |
| 1505 | + } else if (!rvVendor.empty()) { |
| 1506 | + Err(ctx) << getErrorLoc(ctx, loc) |
| 1507 | + << "unknown vendor-specific relocation (" << type.v |
| 1508 | + << ") in namespace '" << rvVendor << "' against symbol '" << &sym |
| 1509 | + << "'"; |
| 1510 | + rvVendor = ""; |
| 1511 | + continue; |
| 1512 | + } |
| 1513 | + |
| 1514 | + rs.scan<ELFT, RelTy>(it, type, rs.getAddend<ELFT>(*it, type)); |
| 1515 | + } |
| 1516 | + |
| 1517 | + // Sort relocations by offset for more efficient searching for |
| 1518 | + // R_RISCV_PCREL_HI20. |
| 1519 | + llvm::stable_sort(sec.relocs(), |
| 1520 | + [](const Relocation &lhs, const Relocation &rhs) { |
| 1521 | + return lhs.offset < rhs.offset; |
| 1522 | + }); |
| 1523 | +} |
| 1524 | + |
| 1525 | +template <class ELFT> void RISCV::scanSection1(InputSectionBase &sec) { |
| 1526 | + const RelsOrRelas<ELFT> rels = sec.template relsOrRelas<ELFT>(); |
| 1527 | + if (rels.areRelocsCrel()) |
| 1528 | + scanSectionImpl<ELFT>(sec, rels.crels); |
| 1529 | + else |
| 1530 | + scanSectionImpl<ELFT>(sec, rels.relas); |
| 1531 | +} |
| 1532 | + |
| 1533 | +void RISCV::scanSection(InputSectionBase &sec) { |
| 1534 | + invokeELFT(scanSection1, sec); |
| 1535 | +} |
0 commit comments