Changeset View
Changeset View
Standalone View
Standalone View
ELF/SyntheticSections.h
Show First 20 Lines • Show All 924 Lines • ▼ Show 20 Lines | |||||
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf | // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf | ||||
class MipsRldMapSection : public SyntheticSection { | class MipsRldMapSection : public SyntheticSection { | ||||
public: | public: | ||||
MipsRldMapSection(); | MipsRldMapSection(); | ||||
size_t getSize() const override { return Config->Wordsize; } | size_t getSize() const override { return Config->Wordsize; } | ||||
void writeTo(uint8_t *Buf) override {} | void writeTo(uint8_t *Buf) override {} | ||||
}; | }; | ||||
class ARMExidxSentinelSection : public SyntheticSection { | // Represent a linker generated .ARM.exidx exception index table section. | ||||
public: | // The .ARM.exidx sections after SHF_LINK_ORDER processing is done form a table | ||||
ARMExidxSentinelSection(); | // that the unwinder can derive (Addresses are encoded as offsets from table): | ||||
size_t getSize() const override { return 8; } | // | Address of function | Unwind instructions for function | | ||||
// where the unwind instructions are either a small number of unwind or the | |||||
grimar: Could you extend the comment? Without reading the patch description it
is probably not clear… | |||||
Sure have done so. This was a valuable exercise as I remembered the precise reason we had to have a terminating sentinel (libunwind bug). peter.smith: Sure have done so. This was a valuable exercise as I remembered the precise reason we had to… | |||||
// special EXIDX_CANTUNWIND entry representing no unwinding information. | |||||
// When an exception is thrown from an address A, the unwinder searches the | |||||
// table for the closest table entry with Address of function <= A. This means | |||||
// that for two consecutive table entries: | |||||
// | A1 | U1 | | |||||
// | A2 | U2 | | |||||
// The range of addresses described by U1 is [A1, A2) | |||||
// | |||||
// There are two cases where we need a linker generated table entry to fixup | |||||
// the address ranges in the table | |||||
// Case 1: | |||||
// - A sentinel entry added with an address higher than all | |||||
// executable sections. This was needed to work around libunwind bug pr31091. | |||||
// - After address assignment we need to find the highest addressed executable | |||||
// section and use the limit of that section so that the unwinder never | |||||
// matches it. | |||||
// Case 2: | |||||
// - InputSections without a .ARM.exidx section (usually from Assembly) | |||||
// need a table entry so that they terminate the range of the previously | |||||
// function. This is pr40277. | |||||
// - We know at creation time the InputSection we need to get the address of. | |||||
// Terminating sentinel entry; IsSentinel = true, LinkSec = nullptr until | |||||
// all InputSections are sorted. | |||||
// Normal entry for a known Section; IsSentinel = false, LinkSec = Section. | |||||
class ARMExidxSyntheticSection : public SyntheticSection { | |||||
public: | |||||
// Use LinkSec = nullptr to create terminating sentinel entry. | |||||
ARMExidxSyntheticSection(InputSection *LinkSec); | |||||
size_t getSize() const override { return sizeof(Data); } | |||||
void writeTo(uint8_t *Buf) override; | void writeTo(uint8_t *Buf) override; | ||||
bool empty() const override; | bool empty() const override; | ||||
static bool classof(const SectionBase *D); | static bool classof(const SectionBase *D); | ||||
// The last section referenced by a regular .ARM.exidx section. | // All instances will have the same unwind instructions. | ||||
// It is found and filled in Writer<ELFT>::resolveShfLinkOrder(). | static const uint8_t Data[8]; | ||||
Not Done ReplyInline ActionsCould it be inlined in the constructor? RawData = { ... }; getSize() seems could either return a constant or RawData.size() then it seems. grimar: Could it be inlined in the constructor?
```
RawData = { ... };
```
`getSize()` seems could… | |||||
Not easily as RawData is a member of a base class. I could add another constructor for SyntheticSection that forwards Data to InputSection but I'm not sure it is worth it. Given that all sections will get the same value I've made it a static. peter.smith: Not easily as RawData is a member of a base class. I could add another constructor for… | |||||
// The sentinel points at the end of that section. | |||||
InputSection *Highest = nullptr; | // At creation time the Sentinel has IsSentinel = true, LinkSec = nullptr | ||||
// A non Sentinel section has IsSentinel = false and LinkSec = Section we | |||||
// are creating entry for. | |||||
InputSection *LinkSec; | |||||
bool IsSentinel; | |||||
}; | }; | ||||
// A container for one or more linker generated thunks. Instances of these | // A container for one or more linker generated thunks. Instances of these | ||||
// thunks including ARM interworking and Mips LA25 PI to non-PI thunks. | // thunks including ARM interworking and Mips LA25 PI to non-PI thunks. | ||||
class ThunkSection : public SyntheticSection { | class ThunkSection : public SyntheticSection { | ||||
public: | public: | ||||
// ThunkSection in OS, with desired OutSecOff of Off | // ThunkSection in OS, with desired OutSecOff of Off | ||||
ThunkSection(OutputSection *OS, uint64_t Off); | ThunkSection(OutputSection *OS, uint64_t Off); | ||||
▲ Show 20 Lines • Show All 90 Lines • Show Last 20 Lines |
Could you extend the comment? Without reading the patch description it
is probably not clear what is EXIDX_CANTUNWIND entry and why
normal and terminating entries are required.