Skip to content

Commit 5660f48

Browse files
rafaelaulermemfrob
authored andcommitted
[BOLT] Write bolt info according to ELF spec
Summary: Follow ELF spec for NOTE sections when writing bolt info. Since tools such as "readelf -n" will not recognize a custom code identifying our new note section, we use GNU "gold linker version" note, tricking readelf into printing bolt info. (cherry picked from FBD6010153)
1 parent 6d46a6d commit 5660f48

File tree

2 files changed

+39
-19
lines changed

2 files changed

+39
-19
lines changed

bolt/RewriteInstance.cpp

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3043,25 +3043,42 @@ void RewriteInstance::finalizeSectionStringTable(ELFObjectFile<ELFT> *File) {
30433043

30443044
void RewriteInstance::addBoltInfoSection() {
30453045
if (opts::AddBoltInfo) {
3046-
std::string Str;
3047-
raw_string_ostream OS(Str);
3046+
std::string DescStr;
3047+
raw_string_ostream DescOS(DescStr);
30483048

3049-
OS << "BOLT revision: " << BoltRevision << ", " << "command line:";
3049+
DescOS << "BOLT revision: " << BoltRevision << ", " << "command line:";
30503050
for (auto I = 0; I < Argc; ++I) {
3051-
OS << " " << Argv[I];
3051+
DescOS << " " << Argv[I];
30523052
}
3053+
DescOS.flush();
3054+
3055+
std::string Str;
3056+
raw_string_ostream OS(Str);
3057+
std::string NameStr = "GNU";
3058+
const uint32_t NameSz = NameStr.size() + 1;
3059+
const uint32_t DescSz = DescStr.size() + 1;
3060+
const uint32_t Type = 4; // NT_GNU_GOLD_VERSION (gold version)
3061+
OS.write(reinterpret_cast<const char*>(&(NameSz)), 4);
3062+
OS.write(reinterpret_cast<const char*>(&(DescSz)), 4);
3063+
OS.write(reinterpret_cast<const char*>(&(Type)), 4);
3064+
OS << NameStr << '\0';
3065+
for (uint64_t I = NameStr.size() + 1;
3066+
I < RoundUpToAlignment(NameStr.size() + 1, 4); ++I) {
3067+
OS << '\0';
3068+
}
3069+
OS << DescStr << '\0';
30533070

30543071
const auto BoltInfo = OS.str();
30553072
const auto SectionSize = BoltInfo.size();
30563073
uint8_t *SectionData = new uint8_t[SectionSize];
30573074
memcpy(SectionData, BoltInfo.data(), SectionSize);
3058-
EFMM->NoteSectionInfo[".bolt_info"] =
3059-
SectionInfo(reinterpret_cast<uint64_t>(SectionData),
3060-
SectionSize,
3061-
/*Alignment=*/1,
3062-
/*IsCode=*/false,
3063-
/*IsReadOnly=*/true,
3064-
/*IsLocal=*/false);
3075+
EFMM->NoteSectionInfo[".note.bolt_info"] =
3076+
SectionInfo(reinterpret_cast<uint64_t>(SectionData), SectionSize,
3077+
/*Alignment=*/1,
3078+
/*IsCode=*/false,
3079+
/*IsReadOnly=*/true,
3080+
/*IsLocal=*/false, 0, 0, 0,
3081+
/*IsELFNote=*/true);
30653082
}
30663083
}
30673084

@@ -3223,7 +3240,9 @@ RewriteInstance::getOutputSections(ELFObjectFile<ELFT> *File,
32233240
outs() << "BOLT-INFO: writing section header for " << SectionName << '\n';
32243241
ELFShdrTy NewSection;
32253242
NewSection.sh_name = SHStrTab.getOffset(SectionName);
3226-
NewSection.sh_type = (SI.IsStrTab ? ELF::SHT_STRTAB : ELF::SHT_PROGBITS);
3243+
NewSection.sh_type =
3244+
(SI.IsStrTab ? ELF::SHT_STRTAB
3245+
: SI.IsELFNote ? ELF::SHT_NOTE : ELF::SHT_PROGBITS);
32273246
NewSection.sh_addr = 0;
32283247
NewSection.sh_offset = SI.FileOffset;
32293248
NewSection.sh_size = SI.Size;

bolt/RewriteInstance.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ struct SectionInfo {
5151
uint64_t FileAddress{0}; /// Address for the output file (final address).
5252
uint64_t FileOffset{0}; /// Offset in the output file.
5353
unsigned SectionID{0}; /// Unique ID used for address mapping.
54+
bool IsELFNote{false}; /// Is ELF note section?
5455

5556
struct Reloc {
5657
uint32_t Offset;
@@ -62,13 +63,13 @@ struct SectionInfo {
6263
/// Pending relocations for the section.
6364
std::vector<Reloc> PendingRelocs;
6465

65-
SectionInfo(uint64_t Address, uint64_t Size, unsigned Alignment,
66-
bool IsCode, bool IsReadOnly,
67-
bool IsLocal, uint64_t FileAddress = 0,
68-
uint64_t FileOffset = 0, unsigned SectionID = 0)
69-
: AllocAddress(Address), Size(Size), Alignment(Alignment), IsCode(IsCode),
70-
IsReadOnly(IsReadOnly), IsLocal(IsLocal), FileAddress(FileAddress),
71-
FileOffset(FileOffset), SectionID(SectionID) {}
66+
SectionInfo(uint64_t Address, uint64_t Size, unsigned Alignment, bool IsCode,
67+
bool IsReadOnly, bool IsLocal, uint64_t FileAddress = 0,
68+
uint64_t FileOffset = 0, unsigned SectionID = 0,
69+
bool IsELFNote = false)
70+
: AllocAddress(Address), Size(Size), Alignment(Alignment), IsCode(IsCode),
71+
IsReadOnly(IsReadOnly), IsLocal(IsLocal), FileAddress(FileAddress),
72+
FileOffset(FileOffset), SectionID(SectionID), IsELFNote(IsELFNote) {}
7273

7374
SectionInfo() {}
7475
};

0 commit comments

Comments
 (0)